bzoj 2120: 数颜色 线段树套平衡树

/**************************************************************
    Problem: 2120
    User: wangyucheng
    Language: C++
    Result: Time_Limit_Exceed
****************************************************************/

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
#define N 13000
#define M 1050000
#define inf 0x3fffffff
int ch[M][2],pre[M],siz[M],val[M],ne[N];
int col[N];
int rt[N*4],L[N*4],R[N*4];
int bb[M];
set<int> jj[1000010];
void up(int x){
   siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
}
void rot(int x){
   int y=pre[x],z=pre[y];
   int k=ch[y][0]==x;
   pre[ch[y][!k]=ch[x][k]]=y;
   pre[ch[x][k]=y]=x;
   pre[x]=z;
   if(!z)rt[bb[y]]=x;
   else ch[z][ch[z][1]==y]=x;
   up(y);
}
void splay(int x,int f){
    int y,z;
    for(;pre[x]!=f;){
        y=pre[x],z=pre[y];
        if(z==f)rot(x);
        else if((ch[y][1]==x)==(ch[z][1]==y))rot(y),rot(x);
        else rot(x),rot(x);
    }
    up(x);
}
int n,m;
int nod;
int mk[N];
void select(int p,int k,int f){
    int x=rt[p];
    while(siz[ch[x][0]]+1!=k){
        if(siz[ch[x][0]]>=k)x=ch[x][0];
        else k-=siz[ch[x][0]]+1,x=ch[x][1];
    }
    splay(x,f);
}
int Bui(int l,int r,int p){
    if(l>r)return 0;
    int k=++nod;
    bb[k]=p;
    int mid=l+r>>1;
    val[k]=mk[mid];
    pre[ch[k][0]=Bui(l,mid-1,p)]=k;
    pre[ch[k][1]=Bui(mid+1,r,p)]=k;
    up(k);
    return k;
}
void build(int l,int r,int k){
    for(int i=2;i<=r-l+2;i++)mk[i]=ne[l+i-2];
    mk[1]=-inf;
    mk[r-l+3]=inf;
    L[k]=l,R[k]=r;
    sort(mk+1,mk+r-l+4);
    rt[k]=Bui(1,r-l+3,k);
    if(l==r)return;
    int mid=l+r>>1;
    build(l,mid,k<<1);
    build(mid+1,r,k<<1|1);
}
int find(int p,int vv){
    int x=rt[p];
    int ma,as=-1;
    while(x){
        if(val[x]<=vv){
           if(as==-1||val[x]>ma)as=x,ma=val[x];
           x=ch[x][1];
        }else x=ch[x][0];
    }
    return as;
}
int count(int p,int vv){
   int as=find(p,vv);
    splay(as,0);
    return siz[ch[as][0]];
}
void dele(int p,int vv){
    int x=find(p,vv);
   splay(x,0);
   int k=siz[ch[x][0]]+1;
   select(p,k-1,0);
   select(p,k+1,rt[p]);
   ch[ch[rt[p]][1]][0]=0;
   splay(ch[rt[p]][1],0);
}
void ins(int p,int vv){
    int x=rt[p],k;
    while(1){
       k=vv>val[x];
       if(!ch[x][k]){
            pre[ch[x][k]=++nod]=x;
            val[nod]=vv;
            splay(nod,0);
          break;
        }
        x=ch[x][k];
    }
}
void change(int l,int k,int vv){
    dele(k,ne[l]);
    ins(k,vv);
    if(L[k]==R[k])return;
   if(R[k<<1]>=l)change(l,k<<1,vv);
   else change(l,k<<1|1,vv);
}
int ans;
void ask(int l,int r,int k,int vv){
    if(L[k]>=l&&R[k]<=r){ans+=count(k,vv);return;}
    if(L[k<<1]<=r&&R[k<<1]>=l)ask(l,r,k<<1,vv);
    if(L[k<<1|1]<=r&&R[k<<1|1]>=l)ask(l,r,k<<1|1,vv);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&col[i]),jj[col[i]].insert(i);
    for(int i=1;i<=n;i++){
         int u=col[i];
         set<int>::iterator it=jj[u].upper_bound(i);
         if(it==jj[u].end())ne[i]=n+i;
         else ne[i]=*it;
    }
    build(1,n,1);
    for(int i=1;i<=m;i++){
        char a;
        int b,c;
        scanf(" %c%d%d",&a,&b,&c);
        if(a==‘R‘){
            set<int>::iterator it=jj[col[b]].find(b),it2,it3;
            it3=it;
            it3++;
            if(it!=jj[col[b]].begin()){
                   it2=it;
                   it2--;
                   if(it3==jj[col[b]].end())change(*it2,1,*it2+n),ne[*it2]=*it2+n;
                   else change(*it2,1,*it3),ne[*it2]=*it3;
            }
            jj[col[b]].erase(it);
            jj[c].insert(b);
            it=jj[c].find(b);
            it2=jj[c].upper_bound(b);
            if(it2!=jj[c].end())change(b,1,*it2),ne[b]=*it2;
            else change(b,1,b+n),ne[b]=b+n;
            it3=it;
            if(it!=jj[c].begin()){
               it3--;
               change(*it3,1,b);
               ne[*it3]=b;
            }
            col[b]=c;
        }else{
            ans=0;
            ask(b,c,1,c);
            printf("%d\n",c-b+1-ans);
        }
    }
}

bzoj 2120: 数颜色 线段树套平衡树

时间: 2024-10-11 07:32:41

bzoj 2120: 数颜色 线段树套平衡树的相关文章

bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)

3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查询k在区间内的后继(后继定义为大于x,且最小的数) Input 第一行两个数 n,

【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

第一种做法(时间太感人): 这题我真的逗了,调了一下午,疯狂造数据,始终找不到错. 后来发现自己sb了,更新那里没有打id,直接套上u了.我.... 调了一下午啊!一下午的时光啊!本来说好中午A掉去学习第二种做法,噗 好吧,现在第一种做法是hld+seg+bst+二分,常数巨大,log^4级别,目前只会这种. 树剖后仍然用线段树维护dfs序区间,然后在每个区间建一颗平衡树,我用treap,(这题找最大啊,,,囧,并且要注意,这里的rank是比他大的数量,so,我们在二分时判断要判断一个范围,即要

BZOJ 1901: Zju2112 Dynamic Rankings 区间k大 带修改 在线 线段树套平衡树

之前写线段树套splay数组版..写了6.2k..然后弃疗了.现在发现还是很水的..嘎嘎.. zju过不了,超时. upd:才发现zju是多组数据..TLE一版才发现.然后改了,MLE...手写内存池..尼玛终于过了..附zju2112代码于后. bzoj倒是过了,1A的感觉还是很爽的..可是时间不好看..这就是所谓\(O(nlog^3n)\)的复杂度的可怜之处么? 写挂的地方: insert一定要是传地址指针进去. delete时先把地址指针delete掉,最后把是地址指针指向左儿子or右儿子

bzoj3295(线段树套平衡树(treap))

3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 861  Solved: 287 [Submit][Status] Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数. Input 输入第一行包含两个整数n和m,即初始元素的个数和删除的元素个数.以

BZOJ3196 二逼平衡树 【线段树套平衡树】

题目 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在区间内的前驱(前驱定义为小于x,且最大的数) 5.查询k在区间内的后继(后继定义为大于x,且最小的数) 输入格式 第一行两个数 n,m 表示长度为n的有序序列和m个操作 第二行有n个数,表示有序序列 下面有m行,opt表示操作标号 若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名 若

树套树-线段树套平衡树

树套树留坑 线段树套平衡树: 二逼平衡树 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<cmath> #include<map> #include<bitset> #pragma GCC optimize(2) #define rep(i,a,b) for(i

bzoj3196 二逼平衡树 线段树套平衡树

题意:您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在区间内的前驱(前驱定义为小于x,且最大的数) 5.查询k在区间内的后继(后继定义为大于x,且最小的数) 题解:树套树,外层是一棵线段树,每个节点下有一棵平衡树(平衡树记录ls,rs,因此记录根节点就可以遍历整棵树),先不考虑空间问题,ask(l,r)可以分成多个线段树区间,每个区间下有平衡树可以查询排名,1&3-5操

bzoj 2120 数颜色

2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 5039  Solved: 2012 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col.为了满足墨墨的要求,你知道你需要干什么了吗? Input 第1行两个整数N,M,分别

【线段树套平衡树】【pb_ds】bzoj3196 Tyvj 1730 二逼平衡树

线段树套pb_ds里的平衡树,在洛谷OJ上测试,后三个测试点TLE #include<cstdio> #include<algorithm> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/tree_policy.hpp> #define N 50010 #define INF 2147483647 using namespace std; using namespace __gnu_pb