zoukankan      html  css  js  c++  java
  • ZJOI2007报表统计

    题目链接

    比较简单的一道平衡树题。

    第三个操作可以直接用map完成(加进去一个数只会让答案变小,于是与它的前面后面一个数做差更新答案即可),只考虑前两个操作。

    ·维护区间内的最大最小值,以及区间相邻两数最小差值。

    ·对于insert x k ,相当于在x+1前插入k,再用一个树状数组维护原数组中的每个数在现在的数组中是第几个,这个操作相当于对 x+1 ~ n 的排名全部加了1。

    复杂度O(nlogn) ,常数略大...

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<map>
    #include<cassert>
    #define P puts("lala")
    #define cp cerr<<"lala"<<endl
    #define ln putchar('
    ')
    #define sp putchar(' ')
    #define pb push_back
    #define pf push_front
    #define fi first
    #define se second 
    #define mkp make_pair
    using namespace std;
    typedef pair<int,int> pii;
    inline void read(int &re)
    {
        char ch=getchar();int g=1;
        while(ch<'0'||ch>'9') {if(ch=='-')g=-1;ch=getchar();}
        re=0;
        while(ch<='9'&&ch>='0') re=(re<<1)+(re<<3)+(ch^48),ch=getchar();
        re*=g;
    }
    typedef long long ll;
    inline void read(ll &re)
    {
        char ch=getchar();ll g=1;
        while(ch<'0'||ch>'9') {if(ch=='-')g=-1;ch=getchar();}
        re=0;
        while(ch<='9'&&ch>='0') re=(re<<1)+(re<<3)+ch-48ll,ch=getchar();
        re*=g;
    }
    
    const int N=500050;
    const int inf=0x3f3f3f3f;
    map<int,int>mp;
    map<int,int>::iterator it,it1;
    
    int dv[N],n,m;
    inline void add(int x,int k)
    {
        for(;x<=n;x+=(x&-x)) dv[x]+=k;
    }
    inline int ask(int x)
    {
        int sum=0;
        for(;x>0;x-=(x&-x)) sum+=dv[x];
        return sum;
    }
    
    int key[N<<1],mind[N<<1],ch[N<<1][2],fa[N<<1],pre[N<<1],nex[N<<1];
    int a[N],sz,root,siz[N<<1];
    
    inline void up(int o)
    {
        mind[o]=min(mind[ch[o][0]],mind[ch[o][1]]);
        pre[o]=key[o];nex[o]=key[o];
        siz[o]=1;
        if(ch[o][0]) 
        {
            mind[o]=min(mind[o],abs(key[o]-nex[ch[o][0]]));
            pre[o]=pre[ch[o][0]];
            siz[o]+=siz[ch[o][0]];
        }
        if(ch[o][1]) 
        {
            mind[o]=min(mind[o],abs(key[o]-pre[ch[o][1]]));
            nex[o]=nex[ch[o][1]];
            siz[o]+=siz[ch[o][1]];
        }
    }
    
    void build(int &o,int l,int r)
    {
        if(l>r) return ;
        o=++sz;
        int mid=l+r>>1;
        key[o]=a[mid];
        siz[o]=1;
        pre[o]=a[mid];nex[o]=a[mid];
        mind[o]=inf;
        if(l==r) return ;
        build(ch[o][0],l,mid-1);build(ch[o][1],mid+1,r);
        fa[ch[o][0]]=o;fa[ch[o][1]]=o;
        up(o);
    }
    
    inline bool ge(int x){return ch[fa[x]][1]==x;}
    inline void rotate(int x)
    {
        int f=fa[x],g=fa[f],wh=ge(x);
        ch[f][wh]=ch[x][wh^1];fa[ch[f][wh]]=f;
        ch[x][wh^1]=f;fa[f]=x;
        fa[x]=g;
        if(g) ch[g][ch[g][1]==f]=x;
        up(f);up(x);
    }
    void splay(int x)
    {
        for(int f;f=fa[x];rotate(x)) if(fa[f]) rotate(ge(x)==ge(f)?f:x);
        root=x;
    }
    int find(int k)
    {
        //assert(k<=siz[root]);
        //assert(k>=1);
        int x=root;
        while(1)
        {
            if(k<=siz[ch[x][0]]) x=ch[x][0];
            else
            {
                k-=siz[ch[x][0]];
                if(k<=1) return x;
                k--;
                x=ch[x][1];
            }
        }
    }
    
    void inspre(int k)
    {
        int x=ch[root][0];
        while(ch[x][1]) x=ch[x][1];
        ch[x][1]=++sz;siz[sz]=1;
        pre[sz]=k;key[sz]=k;nex[sz]=k;
        fa[sz]=x;mind[sz]=inf;
        up(x);
        splay(sz);
    }
    
    char in[50];
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("1.in","r",stdin);freopen("1.out","w",stdout);
    #endif
        int i,j,opt,T;
        mind[0]=inf;
        read(n);read(m);
        for(i=1;i<=n;++i) add(i,1);
        for(i=1;i<=n;++i) read(a[i]),mp[a[i]]++;
        build(root,1,n);
        int minn=inf;
        for(it=mp.begin();it!=mp.end();++it)
        {
            it1=it;
            it1++;
            if(it1!=mp.end()) minn=min(minn,abs( (it->fi)-(it1->fi) ));
            if((it->second)>1) minn=0;
        }
        siz[0]=0;
        for(int cas=1;cas<=m;++cas)
        {
            scanf("%s",in);
            if(in[0]=='I')
            {
                int x,k;read(x);read(k);
                //cerr<<cas<<endl;
                if(x+1>n)
                {
                    int rt=find(siz[root]);
                    splay(rt);
                    root=++sz;
                    ch[sz][0]=rt;
                    fa[rt]=sz;
                    key[sz]=k;mind[sz]=inf;
                    up(sz);
                }
                else
                {
                    int rt=find(ask(x+1));
                    splay(rt);
                    //cout<<siz[root]<<endl;
                    inspre(k);
                }
                mp[k]++;
                it=mp.find(k);
                if((it->se)>1) minn=0;
                else 
                {
                    it1=it;
                    if(it1!=mp.begin())
                    {
                        it1--;
                        minn=min(minn,abs((it1->fi)-k));
                    }
                    it++;
                    if(it!=mp.end()) minn=min(minn,abs((it->fi)-k));
                }
                add(x+1,1);
            }
            else if(in[4]=='G') printf("%d
    ",mind[root]);
            else if(in[4]=='S') printf("%d
    ",minn);
        }
        return 0;
    }
    /*
    
    */
  • 相关阅读:
    JAVA中SpringMVC获取bean方法,在工具类(utils)注入service
    JAVA中json对象转JAVA对象,JSON数组(JSONArray)转集合(List)
    maven中pom文件中scope的作用
    页面图片懒加载、延迟加载(lazyload)
    js(jQuery)获取自定义data属性的值
    ubantu使用小结
    ipmitool管理工具
    大于2T的硬盘怎么分区
    lamp的动静分离部署
    keepalived脑裂问题
  • 原文地址:https://www.cnblogs.com/thkkk/p/7811574.html
Copyright © 2011-2022 走看看