题目大意:
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令:
1 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔
2 R P Col 把第P支画笔替换为颜色Col
思路:
带修改莫队
今天学会了莫队算法
实际上就是分块加上一个大暴力
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #include<map> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 10010 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int sz,n,m; 22 int cnt,Cnt,cx[MAXN<<7],res,block[MAXN],ans[MAXN],g[MAXN]; 23 struct ask{int l,r,t,id;}q[MAXN]; 24 struct Mdf{int x,y;}ch[MAXN/10]; 25 bool cmp(ask a,ask b) 26 { 27 if (block[a.l]==block[b.l]) 28 return a.r<b.r||(a.r==b.r&&a.t<b.t); 29 else return a.l<b.l; 30 } 31 void mdf(int pos,int i) 32 { 33 if(ch[pos].x>=q[i].l&&ch[pos].x<=q[i].r) 34 { 35 cx[g[ch[pos].x]]--; 36 if(!cx[g[ch[pos].x]]) res--; 37 if(!cx[ch[pos].y]) res++; 38 cx[ch[pos].y]++; 39 } 40 swap(g[ch[pos].x],ch[pos].y); 41 } 42 int main() 43 { 44 n=read(),m=read(); 45 sz=sqrt(n);int a,b,c;char s[5]; 46 for(int i=1;i<=n;i++) g[i]=read(),block[i]=(i-1)/sz+1; 47 for(int i=1;i<=m;i++) 48 { 49 scanf("%s",s);a=read(),b=read(); 50 if(s[0]=='Q') 51 q[++cnt].l=a,q[cnt].r=b,q[cnt].id=cnt,q[cnt].t=Cnt; 52 else ch[++Cnt].x=a,ch[Cnt].y=b; 53 } 54 sort(q+1,q+cnt+1,cmp); 55 int l=0,r=0,pos=0; 56 for(int i=1;i<=cnt;i++) 57 { 58 while(l<q[i].l) {cx[g[l]]--;if(!cx[g[l]]) res--;l++;} 59 while(l>q[i].l) {l--;if(!cx[g[l]]) res++; cx[g[l]]++;} 60 while(r<q[i].r) {r++;if(!cx[g[r]]) res++; cx[g[r]]++;} 61 while(r>q[i].r) {cx[g[r]]--;if(!cx[g[r]]) res--; r--;} 62 while(pos<q[i].t) {pos++;mdf(pos,i);} 63 while(pos>q[i].t) {mdf(pos,i);pos--;} 64 ans[q[i].id]=res; 65 } 66 for(int i=1;i<=cnt;i++) printf("%d ",ans[i]); 67 }