1058: [ZJOI2007]报表统计 set+map+priority_queue

对于全局差值,用一个set来维护,用priority_queue来维护最小值。
用两个数组记录每个位置的起点和终点的值,对于相邻差值,用map来维护是否出现过,用set来维护最小值。

#include<iostream>
#include<cstdio>
#include<queue>
#include<set>
#include<map>
#include<algorithm>
#define inf 1000000007
using namespace std;
int n,m;
int st[500005],ed[500005];
multiset<int> a,b;
map<int,int> mp;
priority_queue<int,vector<int>,greater<int> >q;
inline int read()
{
    int a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline void insert(int x)
{
    mp[x]++;
    if (mp[x]==1) a.insert(x);
}
inline void push(int x)
{
    int l=*--b.lower_bound(x),r=*b.lower_bound(x);
    q.push(min(x-l,r-x));
    b.insert(x);
}
int main()
{
    n=read(); m=read();
    b.insert(inf); b.insert(-inf);
    for (int i=1;i<=n;i++)
    {
        int x=read();
        st[i]=ed[i]=x;
        push(x);
    }
    for (int i=2;i<=n;i++) insert(abs(st[i]-st[i-1]));
    for (int i=1;i<=m;i++)
    {
        char opt[15];
        scanf("%s",opt);
        if (opt[0]=='I')
        {
            int p=read(),x=read();
            if (p!=n)
            {
                int t=abs(ed[p]-st[p+1]);
                mp[t]--;
                if (!mp[t]) a.erase(t);
            }
            insert(abs(ed[p]-x));
            insert(abs(st[p+1]-x));
            ed[p]=x; push(x);
        }
        else if (opt[4]=='S') printf("%d\n",q.top());
        else printf("%d\n",*a.begin());
    }
    return 0;
}

你可能感兴趣的:(1058: [ZJOI2007]报表统计 set+map+priority_queue)