P1903 [國家集訓隊]數顏色 / 維護佇列
阿新 • • 發佈:2021-09-04
帶修改莫隊板子
塊長取 \(O(n^{\frac 2 3})\)
總時間複雜度為 \(O(n^{\frac 5 3})\)
\(\text{Code}\)
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #define re register using namespace std; const int N = 133343; int n, m, q1, q2, len, color, buc[1000005], a[N], aa[N], ans[N]; struct node1{int l, r, id, f;}Q[N]; struct node2{int x, y, z;}mf[N]; inline bool cmp(node1 a, node1 b) { return ((a.l/len == b.l/len) ? ((a.r/len == b.r / len) ? (a.id < b.id) : (a.r < b.r)) : (a.l < b.l)); } inline void add(int x){if (!buc[x]) ++color; ++buc[x];} inline void del(int x){--buc[x]; if (!buc[x]) --color;} inline void read(int &x) { x = 0; char ch = getchar(); int f = 1; while (!isdigit(ch)) f = (ch == '-' ? -1 : f), ch = getchar(); while (isdigit(ch)) x = (x<<3) + (x<<1) + (ch ^ 48), ch = getchar(); x *= f; } int main() { read(n), read(m); for(re int i = 1; i <= n; i++) read(a[i]), aa[i] = a[i]; int l, r, lst; char op[3]; for(re int i = 1; i <= m; i++) { scanf("%s", op), read(l), read(r); if (op[0] == 'Q') ++q1, Q[q1] = (node1){l, r, q1, q2}; else mf[++q2] = (node2){l, r, aa[l]}, aa[l] = r; } len = pow((double)n, 2 / 3.0), sort(Q + 1, Q + q1 + 1, cmp), l = r = lst = 0; for(re int i = 1; i <= q1; i++) { for(; lst < Q[i].f; ++lst) { if (l <= mf[lst + 1].x && mf[lst + 1].x <= r) del(mf[lst + 1].z), add(mf[lst + 1].y); a[mf[lst + 1].x] = mf[lst + 1].y; } for(; lst > Q[i].f; --lst) { if (l <= mf[lst].x && mf[lst].x <= r) del(mf[lst].y), add(mf[lst].z); a[mf[lst].x] = mf[lst].z; } for(; l > Q[i].l; l--) add(a[l - 1]); for(; l < Q[i].l; l++) del(a[l]); for(; r < Q[i].r; r++) add(a[r + 1]); for(; r > Q[i].r; r--) del(a[r]); ans[Q[i].id] = color; } for(re int i = 1; i <= q1; i++) printf("%d\n", ans[i]); }