[Bzoj2120]数颜色
如果没有这个修改操作,那么就可以主席树/树状数组乱搞,可以没有如果QAQ。
所以选择莫队来乱搞这个修改操作。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxm = 1e6 + 10; 4 const int maxn = 133334; 5 typedef long long ll; 6 int a[maxm], p[maxm], now[maxm], color[maxm]; 7 struct Q { 8 int l, r, tim, id; 9 }q[maxm]; 10 struct C { 11 int pos, now, old; 12 }c[maxm]; 13 bool cmp(Q a, Q b) { 14 return p[a.l] == p[b.l] ? (p[a.r] == p[b.r] ? a.tim < b.tim : a.r < b.r) : a.l < b.l; 15 } 16 int Ans, ans[maxm], l, r, t; 17 void revise(int x, int val) { 18 color[x] += val; 19 if (val > 0) 20 Ans += color[x] == 1; 21 if (val < 0) 22 Ans -= color[x] == 0; 23 } 24 void go(int x, int d) { 25 if (l <= x && x <= r) 26 revise(d, 1), revise(a[x], -1); 27 a[x] = d; 28 } 29 int main() { 30 int n, m; 31 scanf("%d%d", &n, &m); 32 Ans = r = t = 0, l = 1; 33 int len = pow(n, 0.666666), lenq = 0, lenc = 0; 34 for (int i = 1; i <= n; i++) 35 scanf("%d", &a[i]), now[i] = a[i], p[i] = i / len + 1; 36 char s[3]; 37 int x, y; 38 for (int i = 1; i <= m; i++) { 39 scanf("%s%d%d", s, &x, &y); 40 if (s[0] == 'Q') ++lenq, q[lenq] = { x, y, lenc, lenq }; 41 if (s[0] == 'R') ++lenc, c[lenc] = { x, y, now[x] }, now[x] = y; 42 } 43 sort(q + 1, q + 1 + lenq, cmp); 44 for (int i = 1; i <= lenq; i++) { 45 while (t < q[i].tim)go(c[t + 1].pos, c[t + 1].now), t++; 46 while (t > q[i].tim)go(c[t].pos, c[t].old), t--; 47 while (l < q[i].l)revise(a[l], -1), l++; 48 while (l > q[i].l)revise(a[l - 1], 1), l--; 49 while (r < q[i].r)revise(a[r + 1], 1), r++; 50 while (r > q[i].r)revise(a[r], -1), r--; 51 ans[q[i].id] = Ans; 52 } 53 for (int i = 1; i <= lenq; i++) 54 printf("%d\n", ans[i]); 55 }