TAT
如果只维护画笔的颜色的话显然解决不了查询= =所以考虑维护别的东西。。
令pre[i]表示第pre[i]支画笔颜色同笔i相同且离得最近(pre[i]<i)。对于区间[l,r]中,如果某一支笔x的pre值<l,那么这支笔的颜色是当前区间里第一个出现的,答案+1.
然后我就脑残写了个线段树套treap。。。。。。
外层线段树表示区间,内层按pre值建treap。查询的时候在线段树上拆成一个个区间,然后在treap里查询一下pre值比l小的笔的数目。
因为修改时会改变pre值。。所以我再建了个treap'。。。。。。每种颜色一颗treap',treap'里以笔所在位置为关键字。
所以每次修改某支画笔的颜色的时候,找出它原本的前驱后继改改改,再找出它颜色改变后的前驱后继改改改TAT。。
其实就是维护一下前驱。。每次修改最多改变三支画笔的前驱(自己,原本的后继,颜色改变后的后继)。
最后码了快5k。。。sxbk。。。其实正常做法不是分块暴力吗TAT
本来做好被分块艹的准备了。。结果O(nlog²n)竟然战胜了O(n^1.5)。。。感人肺腑
值得吐槽的是我已经连续若干次因为treap的更新写错而调了1h+了。。。。。。。。。。。
另。。全部加inline后就从#6爬到#2了= =..inline大法好代码长度哭了
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=10023; 7 struct zs{ 8 int num,id; 9 }a[maxn<<1]; 10 struct ask{ 11 int l,r;bool id; 12 }q[maxn]; 13 int i,j,n,m,cnt; 14 int b[maxn],c[maxn<<1],pre[maxn],last[maxn<<1]; 15 int l[maxn*18],r[maxn*18],rnd[maxn*18],sz[maxn*18],w[maxn*18],num[maxn*18],tot; 16 int rt[33233],size; 17 18 int ra;char rx; 19 inline int read(){ 20 rx=getchar(),ra=0; 21 while(rx<'0'||rx>'9')rx=getchar(); 22 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 23 } 24 25 inline void lturn(int &x,int R){ 26 r[x]=l[R],l[R]=x,sz[R]=sz[x],sz[x]=sz[l[x]]+w[x]+sz[r[x]],x=R; 27 } 28 inline void rturn(int &x,int L){ 29 l[x]=r[L],r[L]=x,sz[L]=sz[x],sz[x]=sz[l[x]]+w[x]+sz[r[x]],x=L; 30 } 31 inline void ins(int &x,int v){ 32 if(!x){x=++tot,rnd[x]=rand(),sz[x]=w[x]=1,num[x]=v;return;} 33 ++sz[x]; 34 if(num[x]==v)w[x]++;else 35 if(v<num[x]){ 36 ins(l[x],v); 37 if(rnd[l[x]]<rnd[x])rturn(x,l[x]); 38 }else{ 39 ins(r[x],v); 40 if(rnd[r[x]]<rnd[x])lturn(x,r[x]); 41 } 42 } 43 inline void del(int &x,int v){ 44 if(num[x]==v){ 45 if(w[x]>1)--w[x],--sz[x];else 46 if(!(l[x]&&r[x]))x=l[x]|r[x];else 47 if(rnd[l[x]]<rnd[r[x]])rturn(x,l[x]),del(x,v); 48 else lturn(x,r[x]),del(x,v); 49 }else if(v<num[x]) --sz[x],del(l[x],v); 50 else --sz[x],del(r[x],v); 51 } 52 inline int get(int x,int v){ 53 if(!x)return 0; 54 if(v<num[x])return get(l[x],v);else 55 if(v==num[x])return sz[l[x]];else 56 return get(r[x],v)+w[x]+sz[l[x]]; 57 } 58 inline int query(int l,int r){ 59 if(l>r)swap(l,r); 60 if(l==r)return 1; 61 int l1=l;l+=size,r+=size;int sum=get(rt[l],l1)+get(rt[r],l1); 62 for(;l^r^1;l>>=1,r>>=1){ 63 if(!(l&1))sum+=get(rt[l^1],l1); 64 if(r&1)sum+=get(rt[r^1],l1); 65 } 66 return sum; 67 } 68 //--------------------------------------------------------------- 69 70 int Tl[maxn<<1],Tr[maxn<<1],Trnd[maxn<<1],Tnum[maxn<<1],Trt[maxn<<1],Ttot; 71 int Tpre,Taft; 72 inline void Tlturn(int &x,int R){ 73 Tr[x]=Tl[R],Tl[R]=x,x=R; 74 } 75 inline void Trturn(int &x,int L){ 76 Tl[x]=Tr[L],Tr[L]=x,x=L; 77 } 78 inline void Tins(int &x,int v){ 79 if(!x){x=++Ttot,Trnd[x]=rand(),Tnum[x]=v;return;} 80 if(v<Tnum[x]){ 81 Tins(Tl[x],v); 82 if(Trnd[Tl[x]]<Trnd[x])Trturn(x,Tl[x]); 83 }else{ 84 Tins(Tr[x],v); 85 if(Trnd[Tr[x]]<Trnd[x])Tlturn(x,Tr[x]); 86 } 87 } 88 inline void Tdel(int &x,int v){ 89 if(Tnum[x]==v){ 90 if(!(Tl[x]&&Tr[x]))x=Tl[x]|Tr[x];else 91 if(Trnd[Tl[x]]<Trnd[Tr[x]])Trturn(x,Tl[x]),Tdel(x,v); 92 else Tlturn(x,Tr[x]),Tdel(x,v); 93 }else if(v<Tnum[x]) Tdel(Tl[x],v); 94 else Tdel(Tr[x],v); 95 } 96 inline void getpre(int x,int v){ 97 if(!x)return; 98 if(Tnum[x]<v)Tpre=Tnum[x],getpre(Tr[x],v);else 99 getpre(Tl[x],v); 100 } 101 inline void getaft(int x,int v){ 102 if(!x)return; 103 if(Tnum[x]>v)Taft=Tnum[x],getaft(Tl[x],v);else 104 getaft(Tr[x],v); 105 } 106 107 bool cmp(zs a,zs b){return a.num<b.num;} 108 int main(){ 109 n=read(),m=read();char id; 110 for(i=1;i<=n;i++)a[i].id=i,a[i].num=read();int n1=n; 111 for(i=1;i<=m;i++){ 112 for(id=getchar();id<'A'||id>'Z';id=getchar()); 113 q[i].id=(id=='R');q[i].l=read(),q[i].r=read(); 114 if(q[i].id)a[++n1].id=i+n,a[n1].num=q[i].r; 115 } 116 sort(a+1,a+1+n1,cmp);cnt=0; 117 for(i=1;i<=n1;i++){ 118 if(a[i].num!=a[i-1].num||i==1)c[++cnt]=a[i].num; 119 if(a[i].id<=n)b[a[i].id]=cnt;else q[a[i].id-n].r=cnt; 120 } 121 122 for(size=1;size<n;size<<=1); size--; 123 for(i=1;i<=n;i++){ 124 pre[i]=last[b[i]],last[b[i]]=i; 125 for(j=i+size;j;j>>=1)ins(rt[j],pre[i]); 126 Tins(Trt[b[i]],i); 127 } 128 for(i=1;i<=m;i++) 129 if(!q[i].id) 130 printf("%d ",query(q[i].l,q[i].r)); 131 else if(b[q[i].l]!=q[i].r){ 132 Tpre=0,getpre(Trt[b[q[i].l]],q[i].l),Taft=n+1,getaft(Trt[b[q[i].l]],q[i].l); 133 134 if(Taft<=n){ 135 for(j=Taft+size;j;j>>=1)del(rt[j],pre[Taft]),ins(rt[j],Tpre); 136 pre[Taft]=Tpre; 137 } 138 139 Tpre=0,getpre(Trt[q[i].r],q[i].l),Taft=n+1,getaft(Trt[q[i].r],q[i].l); 140 if(Taft<=n){ 141 for(j=Taft+size;j;j>>=1)del(rt[j],pre[Taft]),ins(rt[j],q[i].l); 142 pre[Taft]=q[i].l; 143 } 144 for(j=q[i].l+size;j;j>>=1)del(rt[j],pre[q[i].l]),ins(rt[j],Tpre); 145 pre[q[i].l]=Tpre, 146 147 Tdel(Trt[b[q[i].l]],q[i].l),b[q[i].l]=q[i].r,Tins(Trt[b[q[i].l]],q[i].l); 148 } 149 return 0; 150 }