• [国家集训队2011]数颜色


    很久以前写的,但因为拿来出题一直没敢FA题解。。。

    这是一份树套树的题解,n,m<=50000应该是可以跑的。

    HH的项链题解

    在那份题解里我写了树套树,其实是因为我要来写这道题懒得改了。。。。

    首先维护100000颗平衡树,每个平衡树里的点颜色一样,这样可以方便的求出同种颜色的前驱后继和修改

    然后树状数组套主席树,修改的话搞出lst值就可以辣

    // It is made by XZZ
    #include<cstdio>
    #include<cstdlib>
    #include<ctime>
    #include<algorithm>
    #include<set>
    #define il inline
    #define rg register
    #define vd void
    #define sta static
    typedef long long ll;
    typedef const int& fast;
    using namespace std;
    il int gi(){
        rg int x=0,f=1;rg char ch=getchar();
        while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    const int maxn=10000;
    int n,m;
    namespace Tree{
        namespace SGT{
            const double alpha=0.7233333;
            int root[1000001],id,val[maxn*50],ch[maxn*50][2],siz[maxn*50],cover[maxn*50],b[maxn*50];
            bool del[maxn*50];
            il int newnode(int _val){val[++id]=_val,ch[id][0]=ch[id][1]=0,siz[id]=cover[id]=1;return id;}
            il vd dfs(const int&rt){
                if(!rt)return;
                dfs(ch[rt][0]);
                if(!del[rt])b[++b[0]]=rt;
                dfs(ch[rt][1]);
            }
            il int divide(int l,int r){
                if(l>r)return 0;
                int mid=(l+r)>>1;
                ch[b[mid]][0]=divide(l,mid-1);
                ch[b[mid]][1]=divide(mid+1,r);
                siz[b[mid]]=siz[ch[b[mid]][0]]+siz[ch[b[mid]][1]]+!del[b[mid]];
                cover[b[mid]]=cover[ch[b[mid]][0]]+cover[ch[b[mid]][1]]+1;
                return b[mid];
            }
            il vd rebuild(int&rt){b[0]=0;dfs(rt);rt=divide(1,b[0]);}
            il int*_Insert(int&rt,fast num){
                if(!rt){rt=newnode(num);return NULL;}
                ++siz[rt],++cover[rt];
                int*ret=_Insert(ch[rt][num>=val[rt]],num);
                if(max(cover[ch[rt][0]],cover[ch[rt][1]])>alpha*cover[rt])ret=&rt;
                return ret;
            }
            il vd Insert(fast y,fast x){int*ls=_Insert(root[y],x);if(ls)rebuild(*ls);}
            il int Rank(fast y,fast x){
                int ret=1,now=root[y];
                while(now)
                    if(x<=val[now])now=ch[now][0];
                    else ret+=siz[ch[now][0]]+!del[now],now=ch[now][1];
                return ret;
            }
            il vd _Delete(fast y,int k){
                int now=root[y];
                while(now){
                    --siz[now];
                    if(!del[now]&&k==siz[ch[now][0]]+1){del[now]=1;return;}
                    if(k<=siz[ch[now][0]])now=ch[now][0];
                    else k-=siz[ch[now][0]]+!del[now],now=ch[now][1];
                }
            }
            il vd Delete(fast y,fast x){
                _Delete(y,Rank(y,x));
                if(siz[root[y]]<cover[root[y]]*alpha)rebuild(root[y]);
            }
        }
        il int lb(fast x){return x&-x;}
        il vd Update(rg int x,fast y){if(!x)return;while(x<=n)SGT::Insert(x,y),x+=lb(x);}
        il vd Update_(rg int x,fast y){if(!x)return;while(x<=n)SGT::Delete(x,y),x+=lb(x);}
        il int Query(rg int l,rg int r,fast y){
            int ret=0;
            while(r)ret+=SGT::Rank(r,y+1)-1,r-=lb(r);
            --l;while(l)ret-=SGT::Rank(l,y+1)-1,l-=lb(l);
            return ret;
        }
    }
    namespace Set FA♂Q{
        set<int>st[1000001];
        il vd del(fast x,fast y){st[x].erase(st[x].find(y));}
        il vd ins(fast x,fast y){st[x].insert(y);}
        il pair<int,int>find(fast x,fast y){
            set<int>::iterator it=st[x].find(y);
            pair<int,int>ret=make_pair(0,0);
            if(it!=st[x].begin())--it,ret.first=*it,++it;
            ++it;if(it!=st[x].end())ret.second=*it;
            return ret;
        }
    }
    int num[maxn],__lst[1000001];
    int main(){
        n=gi();m=gi();
        for(rg int i=1;i<=n;++i)num[i]=gi(),Tree::Update(i,__lst[num[i]]),Set::ins(num[i],i),__lst[num[i]]=i;
        int x,y;pair<int,int>s;char opt[10];
        while(m--){
            scanf("%s",opt),x=gi(),y=gi();
            if(opt[0]=='Q')printf("%d
    ",Tree::Query(x,y,x-1));
            else{
                s=Set::find(num[x],x);
                Tree::Update_(x,s.first),Tree::Update_(s.second,x),Tree::Update(s.second,s.first);
                Set::del(num[x],x),Set::ins((num[x]=y),x);
                s=Set::find(num[x],x);
                Tree::Update_(s.second,s.first),Tree::Update(s.second,x),Tree::Update(x,s.first);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    第36课 经典问题解析三
    第35课 函数对象分析
    67. Add Binary
    66. Plus One
    58. Length of Last Word
    53. Maximum Subarray
    38. Count and Say
    35. Search Insert Position
    28. Implement strStr()
    27. Remove Element
  • 原文地址:https://www.cnblogs.com/xzz_233/p/8321150.html
Copyright © 2020-2023  润新知