题目链接:https://www.luogu.org/problemnew/show/P1903
裸的。。。带修莫队。。。
比较麻烦吧(对我来说是的)
两个变量分开记录查询和修改操作。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #define ri register 6 using namespace std; 7 const int maxn = 1000003; 8 int n, m, bl, answer = 0, qnum = 0, unum = 0, curR, curL, now; 9 int ans[maxn],a[maxn],cnt[maxn]; 10 struct query{ 11 int l, r, p, t; 12 bool operator < (const query &x) const { 13 if(l / bl != x.l / bl) return l / bl < x.l / bl; 14 if(r / bl != x.r / bl) return r / bl < x.r / bl; 15 return t < x.t; 16 } 17 }q[maxn]; 18 struct update{ 19 int pos, val; 20 }u[maxn]; 21 inline void add(int pos) { 22 if(++ cnt[pos] == 1) answer ++; 23 } 24 inline void remove(int pos) { 25 if(-- cnt[pos] == 0) answer --; 26 } 27 inline void change(int now, int i) { 28 if(q[i].l <= u[now].pos && u[now].pos <= q[i].r) { 29 if( --cnt[a[u[now].pos]] == 0 ) answer--; 30 if( ++cnt[u[now].val] == 1) answer++; 31 } 32 swap(a[u[now].pos], u[now].val); 33 } 34 int main() 35 { 36 scanf("%d%d",&n,&m); 37 bl = pow(n,1.0/3); 38 for(ri int i = 1; i <= n; i++) 39 scanf("%d",&a[i]); 40 for(ri int i = 1; i <= m; i++) 41 { 42 int ch, x, y; 43 while((ch = getchar()) != 'Q' && ch != 'R'); 44 scanf("%d%d", &x, &y); 45 if(ch == 'Q') { 46 q[++ qnum].l = x; 47 q[qnum].r = y; 48 q[qnum].t = unum; 49 q[qnum].p = qnum; 50 } else { 51 u[++unum].pos = x; 52 u[unum].val = y; 53 } 54 } 55 sort(q+1,q+qnum+1); 56 curL = q[1].l, curR = curL - 1, now = 0; 57 for(ri int i = 1; i <= qnum; i ++) { 58 while(curL < q[i].l) remove(a[curL ++]); 59 while(curL > q[i].l) add(a[-- curL]); 60 while(curR < q[i].r) add(a[++ curR]); 61 while(curR > q[i].r) remove(a[curR --]); 62 while(now < q[i].t) change(++ now, i); 63 while(now > q[i].t) change(now --, i); 64 ans[q[i].p] = answer; 65 } 66 for(ri int i = 1; i <= qnum; i++) 67 printf("%d ",ans[i]); 68 return 0; 69 }