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

来源:互联网 发布:linux u盘启动 编辑:程序博客网 时间:2024/04/27 13:25

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

#include<iostream>#include<cstdio>#include<queue>#include<set>#include<map>#include<algorithm>#define inf 1000000007using 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;}
0 0