蒟蒻被卡常啦

P1903 [国家集训队] 数颜色 / 维护队列

```cpp #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; typedef long long ll; inline ll read() { ll ans = 0; char last = ' ', ch = getchar(); while (ch < '0' || ch > '9') last = ch, ch = getchar(); while (ch >= '0' && ch <= '9') ans = ans * 10 + ch -'0', ch = getchar(); if (last == '-') return -ans; return ans; } void write(int x) { if (x > 9) write(x / 10); putchar(x%10 + '0'); } const int INF = 0x3f3f3f3f; const int N = 1e6 + 5; int last[N], a[N], bl[N], sum[N]; struct QUERY { int l, r, id, tim; } q[N]; struct CHANGE { int p, col, last; } c[N]; bool cmp_1(const QUERY &a, const QUERY &b) { /*if (bl[a.l] == bl[b.l]) { if (bl[a.r] == bl[b.r]) return a.tim < b.tim; return a.r < b.r; } return a.l < b.l;*/ if (bl[a.l] ^ bl[b.l]) { return bl[a.l] < bl[b.l]; } else { if (bl[a.r] ^ bl[b.r]) return bl[a.r] < bl[b.r]; return bl[a.r] & 1 ? a.r < b.r : a.r > b.r; } } int num = 0; int l; int r; inline void modify(int x, int v) { sum[a[x]] += v; if (sum[a[x]] == 0 && v < 0) num--; if (sum[a[x]] == 1 && v > 0) num++; } inline void go(int tim, int col) { int pos = c[tim].p; if (l <= pos && pos <= r) modify(pos, -1), a[pos] = col, modify(pos, 1); else a[pos] = col; } int n, m; int ans[N]; char op[5]; int main() { //freopen(".in", "r", stdin); //freopen(".out", "w", stdout); n = read(), m = read(); int blo = pow(n, 0.6666667); int tim = 0, t = 0; for (int i = 1; i <= n; ++i) a[i] = read(), bl[i] = i / blo + 1, last[i] = a[i]; for (register int i = 1; i <= m; ++i) { scanf("%c", &op[0]); if (op[0] == 'Q') { ++t; q[t].id = t; q[t].l = read(), q[t].r = read(); q[t].tim = tim; } else { c[++tim].p = read(), c[tim].col = read(); c[tim].last = last[c[tim].p]; last[c[tim].p] = c[tim].col; } } sort(q + 1, q + t + 1, cmp_1); tim = 0; l = 1, r = 0; for (register int i = 1; i <= m; ++i) { while (tim < q[i].tim) go(tim + 1, c[tim + 1].col), tim++; while (tim > q[i].tim) go(tim, c[tim].last), tim--; while (l < q[i].l) {modify(l, -1), ++l;} while (l > q[i].l) {modify(l - 1, 1), --l;} while (r < q[i].r) {modify(r + 1, 1), ++r;} while (r > q[i].r) {modify(r, -1), --r;} ans[q[i].id] = num; } for (int i = 1; i <= t; ++i) { write(ans[i]); puts(""); } return 0; } ```
by Stream月 @ 2020-04-22 23:41:56


@[Stream月](/user/156945) 改块大小
by DepletedPrism @ 2020-04-22 23:51:03


@[DepletedPrism](/user/109751) 造个大样例试块大小?
by Stream月 @ 2020-04-22 23:55:44


@[Stream月](/user/156945) 可以看第一篇题解的... ~~感觉只造一点大样例容易得出在某些特定条件下较快的结果...~~
by DepletedPrism @ 2020-04-23 00:02:09


过了,给你~~魔~~改了一下代码 ```cpp #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize("Ofast") #pragma GCC optimize("inline") #pragma GCC optimize("-fgcse") #pragma GCC optimize("-fgcse-lm") #pragma GCC optimize("-fipa-sra") #pragma GCC optimize("-ftree-pre") #pragma GCC optimize("-ftree-vrp") #pragma GCC optimize("-fpeephole2") #pragma GCC optimize("-ffast-math") #pragma GCC optimize("-fsched-spec") #pragma GCC optimize("unroll-loops") #pragma GCC optimize("-falign-jumps") #pragma GCC optimize("-falign-loops") #pragma GCC optimize("-falign-labels") #pragma GCC optimize("-fdevirtualize") #pragma GCC optimize("-fcaller-saves") #pragma GCC optimize("-fcrossjumping") #pragma GCC optimize("-fthread-jumps") #pragma GCC optimize("-funroll-loops") #pragma GCC optimize("-fwhole-program") #pragma GCC optimize("-freorder-blocks") #pragma GCC optimize("-fschedule-insns") #pragma GCC optimize("inline-functions") #pragma GCC optimize("-ftree-tail-merge") #pragma GCC optimize("-fschedule-insns2") #pragma GCC optimize("-fstrict-aliasing") #pragma GCC optimize("-fstrict-overflow") #pragma GCC optimize("-falign-functions") #pragma GCC optimize("-fcse-skip-blocks") #pragma GCC optimize("-fcse-follow-jumps") #pragma GCC optimize("-fsched-interblock") #pragma GCC optimize("-fpartial-inlining") #pragma GCC optimize("no-stack-protector") #pragma GCC optimize("-freorder-functions") #pragma GCC optimize("-findirect-inlining") #pragma GCC optimize("-frerun-cse-after-loop") #pragma GCC optimize("inline-small-functions") #pragma GCC optimize("-finline-small-functions") #pragma GCC optimize("-ftree-switch-conversion") #pragma GCC optimize("-foptimize-sibling-calls") #pragma GCC optimize("-fexpensive-optimizations") #pragma GCC optimize("-funsafe-loop-optimizations") #pragma GCC optimize("inline-functions-called-once") #pragma GCC optimize("-fdelete-null-pointer-checks") #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; typedef long long ll; //char buf[1<<23],*p1=buf,*p2=buf; //#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) inline ll read() { ll ans = 0; char last = ' ', ch = getchar(); while (ch < '0' || ch > '9') last = ch, ch = getchar(); while (ch >= '0' && ch <= '9') ans = ans * 10 + ch -'0', ch = getchar(); if (last == '-') return -ans; return ans; } void write(int x) { if (x > 9) write(x / 10); putchar(x%10 + '0'); } const int INF = 0x3f3f3f3f; const int N = 1e6 + 5; int blo,last[N], a[N], bl[N], sum[N]; struct QUERY { int l, r, id, tim; bool operator < (QUERY a){ if((l / blo) ^ (a.l / blo)) return l / blo < a.l / blo; else if((r / blo) ^ (a.r / blo)) return r / blo < a.r / blo; else return tim < a.tim; } } q[N]; struct CHANGE { int p, col, last; } c[N]; bool cmp_1(const QUERY &a, const QUERY &b) { /*if (bl[a.l] == bl[b.l]) { if (bl[a.r] == bl[b.r]) return a.tim < b.tim; return a.r < b.r; } return a.l < b.l;*/ if (bl[a.l] ^ bl[b.l]) { return bl[a.l] < bl[b.l]; } else { if (bl[a.r] ^ bl[b.r]) return bl[a.r] < bl[b.r]; return a.tim < b.tim; } } int num = 0; int l; int r; inline void modify(int x, int v) { sum[a[x]] += v; if (sum[a[x]] == 0 && v < 0) num--; if (sum[a[x]] == 1 && v > 0) num++; num -= !--sum[a[x]]; num += !sum[a[x]] ++; } inline void go(int tim, int col) { int pos = c[tim].p; if (l <= pos && pos <= r) num -= !--sum[a[pos]], a[pos] = col, num += !sum[a[pos]] ++; else a[pos] = col; } int n, m; int ans[N]; char op[5]; int main() { //freopen(".in", "r", stdin); //freopen(".out", "w", stdout); n = read(), m = read(); //int blo = pow(n, 0.6666667); int tim = 0, t = 0; for (int i = 1; i <= n; ++i) a[i] = read(), last[i] = a[i]; for (register int i = 1; i <= m; ++i) { if (getchar() == 'Q') { ++t; q[t].id = t; q[t].l = read(), q[t].r = read(); q[t].tim = tim; } else { c[++tim].p = read(), c[tim].col = read(); c[tim].last = last[c[tim].p]; last[c[tim].p] = c[tim].col; } } blo = ceil(exp((log(n)+log(tim))/3)); // for (int i = 1; i <= n; ++i) { // bl[i] = i / blo + 1; // } sort(q + 1, q + t + 1); tim = 0; l = 1, r = 0; for (register int i = 1; i <= m; ++i) { while (tim < q[i].tim) { tim ++; int pos = c[tim].p; if (l <= pos && pos <= r) num -= !--sum[a[pos]], a[pos] = c[tim].col, num += !sum[a[pos]] ++; else a[pos] = c[tim].col; } while (tim > q[i].tim) { int pos = c[tim].p; if (l <= pos && pos <= r) num -= !--sum[a[pos]], a[pos] = c[tim].last, num += !sum[a[pos]] ++; else a[pos] = c[tim].last; tim --; } // while (tim < q[i].tim) go(tim + 1, c[tim + 1].col), tim++; // while (tim > q[i].tim) go(tim, c[tim].last), tim--; while (l < q[i].l) num -= !--sum[a[l++]]; while (l > q[i].l) num += !sum[a[--l]] ++; while (r < q[i].r) num += !sum[a[++r]] ++; while (r > q[i].r) num -= !--sum[a[r --]]; ans[q[i].id] = num; } for (int i = 1; i <= t; ++i) { write(ans[i]); puts(""); } return 0; } ```
by __ykl @ 2020-04-23 07:29:54


~~改完居然跑的比我自己的还快~~
by __ykl @ 2020-04-23 07:33:47


火车头再世。。
by bovine__kebi @ 2020-04-23 08:18:11


@[刘开予2019](/user/172763) 多谢,带佬orz
by Stream月 @ 2020-04-23 09:08:55


|