bzoj2120: 数颜色
Posted AKCqhzdy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2120: 数颜色相关的知识,希望对你有一定的参考价值。
这题其实可以用更加高级的东西做,但是我为了学带修莫队(优雅的打暴力)就用这个做了。
相较于莫队,带修莫队需要多维护一个东西——时间。怎么维护?想想l,r的维护方式(笑)当然就是暴力啦!
对于当前位置当前时间,保存他上一个颜色和下一个颜色,在普通莫队之前先将时间暴力解决,然后就和普通莫队无异了。
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; struct Query { int l,r,T,id; }q[11000];int qlen; struct Change { int x,be,af; }c[11000];int clen,last[11000]; int st[11000]; bool cmp(Query a,Query b) { if( st[a.l]<st[b.l] || (st[a.l]==st[b.l]&&st[a.r]<st[b.r]) || (st[a.l]==st[b.l]&&st[a.r]==st[b.r]&&a.T<b.T) )return true; return false; } int a[11000],col[1100000]; int as[11000],ans; void update(int i,int k) { col[i]+=k; if(k==1&&col[i]==1)ans++; if(k==-1&&col[i]==0)ans--; } void solve() { int l=1,r=0,T=0; for(int i=1;i<=qlen;i++) { while(T>q[i].T) { if(l<=c[T].x&&c[T].x<=r) update(c[T].be,1), update(a[c[T].x],-1); a[c[T].x]=c[T].be; T--; } while(T<q[i].T) { T++; if(l<=c[T].x&&c[T].x<=r) update(c[T].af,1), update(a[c[T].x],-1); a[c[T].x]=c[T].af; } while(l>q[i].l)l--, update(a[l],1); while(r<q[i].r)r++, update(a[r],1); while(l<q[i].l)update(a[l],-1), l++; while(r>q[i].r)update(a[r],-1), r--; as[q[i].id]=ans; } } char ss[5]; int main() { int n,m,x,y; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); last[i]=a[i]; } for(int i=1;i<=m;i++) { scanf("%s%d%d",ss+1,&x,&y); if(ss[1]==‘Q‘) { qlen++; q[qlen].l=x;q[qlen].r=y; q[qlen].T=clen;q[qlen].id=qlen; } if(ss[1]==‘R‘) { clen++; c[clen].x=x;c[clen].af=y; c[clen].be=last[x],last[x]=y; } } int fk=int(pow(n,0.666666)); for(int i=1;i<=n;i++)st[i]=(i-1)/fk+1; sort(q+1,q+qlen+1,cmp); solve(); for(int i=1;i<=qlen;i++)printf("%d\n",as[i]); return 0; }
以上是关于bzoj2120: 数颜色的主要内容,如果未能解决你的问题,请参考以下文章