洛谷 P3939 数颜色(主席树)

 

 

 

题目要用权值线段树来解决没有问题,但是权值线段树还要维护所出现的区间,采用主席树,每一种颜色建一棵树,记录其所在的位置,由于建树过程中需要动态开点,更新操作时不需要动态开点,所以要特判一下是否要开点

const int N=3e5+5;

    int n,m;
    int i,j,k;
    int a[N];
    struct Node
    {
        int l,r;
        int sum;
        #define lson id<<1
        #define rson id<<1|1
    }t[N*40];
    vector<int> v;
    int root[N],tot;

void update(int l,int r,int &now,int pos,int c)
{
    if(!now) now=++tot;
    t[now].sum+=c;
    if(l==r) return ;
    else {
        int mid=l+r>>1;
        if(mid>=pos) update(l,mid,t[now].l,pos,c);
        else update(mid+1,r,t[now].r,pos,c);
    }
}

int query(int L,int R,int l,int r,int now)
{
    if(L>=l && r>=R) return t[now].sum;
    else{
        int mid=L+R>>1;
        int ans=0;
        if(mid>=l) ans+=query(L,mid,l,r,t[now].l);
        if(r>=mid+1) ans+=query(mid+1,R,l,r,t[now].r);
        return ans;
    }
}

signed main()
{
    //IOS;
    while(~sdd(n,m)){
        for(int i=1;i<=n;i++){ sd(a[i]); update(1,n,root[a[i]],i,1); }
        for(int i=1;i<=m;i++){
            int x,y,opt,c,ans;
            sdd(opt,x);
            if(opt==1){
                sdd(y,c);
                ans=query(1,n,x,y,root[c]);
                pd(ans);
            } else{
                update(1,n,root[a[x]],x,-1);
                update(1,n,root[a[x]],x+1,1);
                update(1,n,root[a[x+1]],x+1,-1);
                update(1,n,root[a[x+1]],x,1);
                swap(a[x],a[x+1]);
            }
        }
    }
    //PAUSE;
    return 0;
}

 

相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页