刷题集--报表统计

题意:小Q的妈妈是一个出纳,经常需要做一些统计报表的工作。今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一。
经过仔细观察,小Q发现统计一张报表实际上是维护一个非负整数数列,并且进行一些查询操作。
在最开始的时候,有一个长度为N的整数序列,并且有以下三种操作:
INSERT i k 在原数列的第i个元素后面添加一个新元素k;如果原数列的第i个元素已经添加了若干元素,则添加在这些元素的最后(见下面的例子)
MIN_GAP 查询相邻两个元素的之间差值(绝对值)的最小值
MIN_SORT_GAP 查询所有元素中最接近的两个元素的差值(绝对值)

例如一开始的序列为
5 3 1

执行操作INSERT 2 9将得到:
5 3 9 1
此时MIN_GAP为2,MIN_SORT_GAP为2。

再执行操作INSERT 2 6将得到:
5 3 9 6 1

注意这个时候原序列的第2个元素后面已经添加了一个9,此时添加的6应加在9的后面。这个时候MIN_GAP为2,MIN_SORT_GAP为1。
于是小Q写了一个程序,使得程序可以自动完成这些操作,但是他发现对于一些大的报表他的程序运行得很慢,你能帮助他改进程序么?

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

开个vector表示某一位之后插的数,再开两个map(multiset也行)来维护所需两个答案就好了

#pragma GCC optimize(3,"inline","Ofast")
#include<bits/stdc++.h>
#define iter map<int,int>::iterator
using namespace std;
const int N=5e5+10;
void read(int &x)
{
    char c=getchar();x=0;int r=0;
    while(!isdigit(c))
    {
        if(c=='-')r=1;
        c=getchar();
    }
    while(isdigit(c))x=x*10+c-48,c=getchar();
    if(r)x=-x;
}
map<int,int>vis,viss;
vector<int>mp[N];
int n,m,a[N],res=2e9;
void gx(int x)
{
    iter bf;
    bf=viss.lower_bound(x);
    if(bf!=viss.end())res=min(res,abs(bf->first-x));
    if(bf!=viss.begin())--bf,res=min(res,abs(x-bf->first));
}
int main()
{
    int nw,bf,ps,tmp;char s[20];iter tp;
    read(n),read(m);
    for(int i=1;i<=n;i++)
    {
        read(nw);
        mp[i].push_back(nw);
        if(i>1)vis[abs(nw-mp[i-1][0])]++;
        gx(nw),viss[nw]++;
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%s",s);
        if(s[0]=='I')
        {
            read(ps),read(nw);
            gx(nw);
            if(ps!=n)
            {
                vis[tmp=abs(mp[ps+1][0]-mp[ps][mp[ps].size()-1])]--;
                if(!vis[tmp])vis.erase(tmp);
                vis[abs(mp[ps][mp[ps].size()-1]-nw)]++;
                vis[abs(mp[ps+1][0]-nw)]++;
                mp[ps].push_back(nw),viss[nw]++;
            }
            else vis[abs(mp[ps][mp[ps].size()-1]-nw)]++,viss[nw]++,mp[ps].push_back(nw);
        }
        else if(s[4]=='G')
        {
            tp=vis.begin();
            printf("%d\n",tp->first);
        }
        else printf("%d\n",res);
    }
}

猜你喜欢

转载自blog.csdn.net/caoyang1123/article/details/82619777