墨墨購買了一套N支彩色畫筆(其中有些顏色可能相同),擺成一排,你須要回答墨墨的提問。墨墨會像你發佈以下指令: 一、 Q L R表明詢問你從第L支畫筆到第R支畫筆中共有幾種不一樣顏色的畫筆。 二、 R P Col 把第P支畫筆替換爲顏色Col。爲了知足墨墨的要求,你知道你須要幹什麼了嗎?算法
本文版權歸ljh2000和博客園共有,歡迎轉載,但須保留此聲明,並給出原文連接,謝謝合做。ios
墨墨購買了一套N支彩色畫筆(其中有些顏色可能相同),擺成一排,你須要回答墨墨的提問。墨墨會像你發佈以下指令: 一、 Q L R表明詢問你從第L支畫筆到第R支畫筆中共有幾種不一樣顏色的畫筆。 二、 R P Col 把第P支畫筆替換爲顏色Col。爲了知足墨墨的要求,你知道你須要幹什麼了嗎?算法
第1行兩個整數N,M,分別表明初始畫筆的數量以及墨墨會作的事情的個數。第2行N個整數,分別表明初始畫筆排中第i支畫筆的顏色。第3行到第2+M行,每行分別表明墨墨會作的一件事情,格式見題幹部分。spa
對於每個Query的詢問,你須要在對應的行中給出一個數字,表明第L支畫筆到第R支畫筆中共有幾種不一樣顏色的畫筆。code
對於100%的數據,N≤10000,M≤10000,修改操做很少於1000次,全部的輸入數據中出現的全部整數均大於等於1且不超過10^6。blog
1 //It is made by ljh2000 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <set> 13 #include <string> 14 using namespace std; 15 typedef long long LL; 16 const int MAXN = 10011; 17 int n,m,a[MAXN],last[MAXN],cnt1,cnt2,block; 18 int L,R,head,ans,cnt[1000011],A[MAXN]; 19 char ch[12]; 20 struct ask{int l,r,lb,rb,tim,id;}q[MAXN]; 21 struct modify{int x,y,last;}r[MAXN]; 22 inline bool cmp(ask q,ask qq){ 23 if(q.lb==qq.lb) { 24 if(q.rb==qq.rb) return q.tim<qq.tim; 25 return q.rb<qq.rb; 26 } 27 return q.lb<qq.lb; 28 } 29 inline int getb(int x){ return (x-1)/block+1; } 30 inline int getint(){ 31 int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar(); 32 if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w; 33 } 34 35 inline void change(int x,int col){ 36 if(L<=x&&x<=R) { 37 cnt[a[x]]--; if(cnt[a[x]]==0) ans--; 38 a[x]=col; 39 if(cnt[a[x]]==0) ans++; cnt[a[x]]++; 40 } 41 else a[x]=col; 42 } 43 44 inline void update(int x,int type){ 45 int cun=cnt[a[x]]; cnt[a[x]]+=type; 46 if(cun==0 && cnt[a[x]]==1) ans++; 47 else if(cun==1 && cnt[a[x]]==0) ans--; 48 } 49 50 inline void work(){ 51 n=getint(); m=getint(); for(int i=1;i<=n;i++) a[i]=getint(),last[i]=a[i]; 52 block=sqrt(n); 53 for(int i=1;i<=m;i++) { 54 scanf("%s",ch); 55 if(ch[0]=='R') { 56 r[++cnt1].x=getint(); 57 r[cnt1].y=getint(); 58 r[cnt1].last=last[r[cnt1].x]; 59 last[r[cnt1].x]=r[cnt1].y; 60 } 61 else{ 62 q[++cnt2].l=getint(); q[cnt2].r=getint(); q[cnt2].id=cnt2; 63 q[cnt2].lb=getb(q[cnt2].l); q[cnt2].rb=getb(q[cnt2].r); 64 q[cnt2].tim=cnt1; 65 } 66 } 67 sort(q+1,q+cnt2+1,cmp); L=1; R=0; head=0; 68 for(int i=1;i<=cnt2;i++) { 69 while(head>q[i].tim) { 70 change(r[head].x,r[head].last); 71 head--; 72 } 73 while(head<q[i].tim) { 74 head++; 75 change(r[head].x,r[head].y); 76 } 77 while(R<q[i].r) R++,update(R,1); 78 while(L>q[i].l) L--,update(L,1); 79 while(R>q[i].r) update(R,-1),R--; 80 while(L<q[i].l) update(L,-1),L++; 81 A[q[i].id]=ans; 82 } 83 for(int i=1;i<=cnt2;i++) printf("%d\n",A[i]); 84 } 85 86 int main() 87 { 88 work(); 89 return 0; 90 }