BZOJ 1058 报表统计

Posted on 2017-01-25 14:35  ziliuziliu  阅读(110)  评论(0编辑  收藏  举报

基本思路正确。注意两点:

1.MIN_SORT_GAP不用以第二个set实现。这个答案一定是单调的。

2.lower_bound巨慢巨慢巨慢巨慢巨慢巨慢巨慢用lower_bound和set是10s与1h的区别。

  能不用尽量不用。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#define maxn 1000500
#define inf 1000000007
using namespace std;
int n,m,a[maxn],b[maxn],last[maxn],tot,nxt[maxn],pre[maxn],x,y,mn=inf;
multiset <int> s1,s3;
multiset <int> ::iterator it1,it2,it3;
char s[10];
int read()
{
    char ch;int data=0,f=1;
    while (ch<'0' || ch>'9')
    {
        if (ch=='-') f=-1;
        ch=getchar();
    }
    while (ch>='0' && ch<='9')
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return data*f;
}
void add1()
{
    nxt[tot]=nxt[last[x]];pre[tot]=last[x];
    pre[nxt[last[x]]]=tot;nxt[last[x]]=tot;last[x]=tot;
    if (nxt[tot]!=-1)
    {
        it1=s1.find(abs(a[nxt[tot]]-a[pre[tot]]));
        s1.erase(it1);
        s1.insert(abs(a[nxt[tot]]-a[tot]));
    }
    s1.insert(abs(a[pre[tot]]-a[tot]));
}
void add2()
{
    s3.insert(a[tot]);it1=s3.find(a[tot]);
    if (it1!=s3.begin())
    {
        it1--;
        mn=min(mn,a[tot]-*it1);
        it1++;
    }
    it1++;
    if (it1!=s3.end()) mn=min(mn,*it1-a[tot]);
}
int main()
{
    n=read();m=read();tot=n;
    for (int i=1;i<=n;i++)
    {
        a[i]=read();b[i]=a[i];s3.insert(a[i]);
        last[i]=i;nxt[i]=i+1;pre[i]=i-1;
    }
    pre[1]=nxt[n]=-1;
    for (int i=1;i<=n-1;i++) s1.insert(abs(a[i+1]-a[i]));
    for (it1=s3.begin();it1!=s3.end();it1++)
    {
        if (it1!=s3.begin()) mn=min(mn,*it1-*it2);
        it2=it1;
    }
    for (int i=1;i<=m;i++)
    {
        scanf("%s",s);
        if (s[0]=='I')
        {
            scanf("%d%d",&x,&y);a[++tot]=y;
            add1();
            add2();
        }
        else if (s[4]=='S') printf("%d\n",mn);
        else printf("%d\n",*s1.begin());
    }
    return 0;
}