Bzoj 2453: 维护队列 && Bzoj 2120: 数颜色 分块,bitset
2453: 维护队列
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 578 Solved: 247
[Submit][Status][Discuss]
Description
你小时候玩过弹珠吗?
小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N。为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少。当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色。但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助。
Input
输入文件第一行包含两个整数N和M。
第二行N个整数,表示初始队列中弹珠的颜色。
接下来M行,每行的形式为“Q L R”或“R x c”,“Q L R”表示A想知道从队列第L个弹珠到第R个弹珠中,一共有多少不同颜色的弹珠,“R x c”表示A把x位置上的弹珠换成了c颜色。
Output
对于每个Q操作,输出一行表示询问结果。
Sample Input
2 3
1 2
Q 1 2
R 1 2
Q 1 2
Sample Output
2
1
1
HINT
对于100%的数据,有1 ≤ N ≤ 10000, 1 ≤ M ≤ 10000,小朋友A不会修改超过1000次,所有颜色均用1到10^6的整数表示。
Source
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define MAXN 10010 4 #define MAXM 1000010 5 int n,a[MAXN],last[MAXN],pre[MAXM],block,pos[MAXN],h[MAXN]; 6 int read() 7 { 8 int s=0,fh=1;char ch=getchar(); 9 while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();} 10 while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();} 11 return s*fh; 12 } 13 void cl(int k) 14 { 15 int l=(k-1)*block+1,r=min(n,k*block),i; 16 for(i=l;i<=r;i++)a[i]=last[i]; 17 sort(a+l,a+r+1); 18 } 19 void Change(int x,int c) 20 { 21 int i,t; 22 for(i=1;i<=n;i++)pre[h[i]]=0; 23 h[x]=c; 24 for(i=1;i<=n;i++) 25 { 26 t=last[i]; 27 last[i]=pre[h[i]]; 28 if(t!=last[i])cl(pos[i]); 29 pre[h[i]]=i; 30 } 31 } 32 int Find(int k,int ll) 33 { 34 int l=(k-1)*block+1,r=min(k*block,n),mid,t=0; 35 while(l<=r) 36 { 37 mid=(l+r)/2; 38 if(a[mid]>=ll)r=mid-1; 39 else if(a[mid]<ll)t=mid,l=mid+1; 40 } 41 if(t==0)return 0; 42 else return t-((k-1)*block+1)+1; 43 } 44 int Query(int l,int r) 45 { 46 int ans=0,i; 47 if(pos[l]==pos[r]) 48 { 49 for(i=l;i<=r;i++)if(last[i]<l)ans++; 50 } 51 else 52 { 53 for(i=l;i<=pos[l]*block;i++)if(last[i]<l)ans++; 54 for(i=(pos[r]-1)*block+1;i<=r;i++)if(last[i]<l)ans++; 55 for(i=pos[l]+1;i<=pos[r]-1;i++)ans+=Find(i,l); 56 } 57 return ans; 58 } 59 int main() 60 { 61 int M,i,m,s1,s2; 62 char fh[2]; 63 n=read();M=read(); 64 block=(int)sqrt(n); 65 memset(last,0,sizeof(last)); 66 memset(pre,0,sizeof(pre)); 67 for(i=1;i<=n;i++) 68 { 69 h[i]=read(); 70 last[i]=pre[h[i]]; 71 pre[h[i]]=i; 72 pos[i]=(i-1)/block+1; 73 } 74 if(block*block==n)m=n/block; 75 else m=n/block+1; 76 for(i=1;i<=m;i++)cl(i); 77 for(i=1;i<=M;i++) 78 { 79 scanf("\n%s",fh);s1=read();s2=read(); 80 if(fh[0]=='Q') 81 { 82 printf("%d\n",Query(s1,s2)); 83 } 84 else Change(s1,s2); 85 } 86 return 0; 87 }
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a[10010]; 4 bitset<1000010> vis; 5 int main() 6 { 7 int n,m,i,l,r,sum,j; 8 char fh; 9 scanf("%d %d",&n,&m); 10 for(i=1;i<=n;i++)scanf("%d",&a[i]); 11 for(i=1;i<=m;i++) 12 { 13 scanf("\n%c %d %d",&fh,&l,&r); 14 if(fh=='Q') 15 { 16 vis.reset(); 17 sum=0; 18 for(j=l;j<=r;j++)if(vis[a[j]]==0){sum++;vis[a[j]]=1;} 19 printf("%d\n",sum); 20 } 21 else 22 { 23 a[l]=r; 24 } 25 } 26 return 0; 27 }