bzoj 2120: 数颜色
Posted xiyuedong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2120: 数颜色相关的知识,希望对你有一定的参考价值。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #define M 1000009 6 using namespace std; 7 int block,n,m,a[M],b[M],pre[M],pos[M],last[M],l[M],r[M],m1; 8 int ask(int a1,int a2) 9 { 10 int ans=0; 11 if(pos[a1]==pos[a2]) 12 { 13 for(int i=a1;i<=a2;i++) 14 if(b[i]<a1) 15 ans++; 16 } 17 else 18 { 19 for(int i=a1;i<=r[pos[a1]];i++) 20 if(b[i]<a1) 21 ans++; 22 for(int i=l[pos[a2]];i<=a2;i++) 23 if(b[i]<a1) 24 ans++; 25 for(int i=pos[a1]+1;i<pos[a2];i++) 26 ans+=lower_bound(pre+l[i],pre+r[i]+1,a1)-pre-l[i]; 27 } 28 return ans; 29 } 30 void jian(int i) 31 { 32 l[i]=(i-1)*block+1; 33 r[i]=min(n,i*block); 34 for(int j=l[i];j<=r[i];j++) 35 pre[j]=b[j]; 36 sort(pre+l[i],pre+r[i]+1); 37 } 38 void gai(int x,int y) 39 { 40 for(int i=1;i<=n;i++) 41 last[a[i]]=0; 42 a[x]=y; 43 for(int i=1;i<=n;i++) 44 { 45 int t=b[i]; 46 b[i]=last[a[i]]; 47 if(t!=last[a[i]]) 48 jian(pos[i]); 49 last[a[i]]=i; 50 } 51 } 52 int main() 53 { 54 scanf("%d%d",&n,&m1); 55 for(int i=1;i<=n;i++) 56 scanf("%d",&a[i]); 57 block=(int)sqrt(n+log(2*n)/log(2)); 58 m=n/block; 59 if(n%block) 60 m++; 61 for(int i=1;i<=n;i++) 62 { 63 b[i]=last[a[i]]; 64 last[a[i]]=i; 65 pos[i]=(i-1)/block+1; 66 } 67 for(int i=1;i<=m;i++) 68 jian(i); 69 for(int i=1;i<=m1;i++) 70 { 71 char ch[5]; 72 int a1,a2; 73 scanf("%s%d%d",ch,&a1,&a2); 74 if(ch[0]==‘Q‘) 75 printf("%d\n",ask(a1,a2)); 76 else 77 gai(a1,a2); 78 } 79 return 0; 80 }
暴力分块,每个点存下一个与他相同颜色的在哪,每个块内排序,找的时候首尾暴力判断每个点下一个颜色在不在区间外,不在就答案加加,中间二分。修改时重建每个点存的下一个点,
如果改了,就重建这个块。
以上是关于bzoj 2120: 数颜色的主要内容,如果未能解决你的问题,请参考以下文章