bzoj2821 作詩(Poetize)
阿新 • • 發佈:2017-05-04
pro 感覺 clas reg memset bbf sort ... oid
傳送門:http://www.lydsy.com/JudgeOnline/problem.php?id=2821
【題解】
今天看了黃學長的分塊專項 感覺十分科學就來剛剛分塊了。
這題我們套用區間眾數的辦法。令f[i,j]表示i塊到j塊的答案,g[i,j]表示1...i塊,數字為j的有多少個。
然後我們大區間個數可以直接調用,兩邊暴力做。
註意清零問題不能出現復雜度退化。
有兩種辦法,一個是把所有即將出現的數的位置都清空或賦值,一種是排序後,找到第一個的時候賦值,後面累加。
後面那個是popoqqq大爺寫的(似乎強行多了個log)
事實證明這個log很慢的。。
大概……也就兩倍把
兩份代碼:
O(n根號n)
# include <stdio.h> # include <string.h> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 1e5 + 10, N = 320, BLOCK = 350; # define RG register # define ST staticView Codeint n, C, q, B; int a[M], bl[M]; int bst[N], bnd[N]; int t[M]; int f[N][N]; int g[N][M]; // 1..i block j appear ? time inline void prepare(int x) { int cur = 0, tem = x; memset(t, 0, sizeof t); for (int i=bst[x]; i<=n; ++i) { ++t[a[i]]; if(t[a[i]]&1) { if(t[a[i]] == 1); else --cur; } else ++cur; if(bnd[tem] == i) { f[x][tem] = cur; ++tem; } } } int main() { scanf("%d%d%d", &n, &C, &q); for (int i=1; i<=n; ++i) { scanf("%d", a+i); bl[i] = (i-1)/BLOCK+1; } B = bl[n]; for (int i=1; i<=B; ++i) bst[i] = (i-1)*BLOCK+1, bnd[i] = min(n, i*BLOCK); for (int i=1; i<=B; ++i) prepare(i); for (int i=1; i<=B; ++i) { for (int j=1; j<=C; ++j) g[i][j] = g[i-1][j]; for (int j=bst[i]; j<=bnd[i]; ++j) g[i][a[j]] ++; } int l, r, lst=0; while(q--) { scanf("%d%d", &l, &r); l = (l+lst)%n+1, r = (r+lst)%n+1; if(l>r) swap(l, r); // printf("%d %d\n", l, r); if(bl[l] == bl[r]) { int cur = 0; for (int i=l; i<=r; ++i) t[a[i]] = 0; for (int i=l; i<=r; ++i) { ++t[a[i]]; if(t[a[i]]&1) { if(t[a[i]] == 1); else --cur; } else ++cur; } printf("%d\n", lst = cur); continue; } int cur = 0; if(bl[r]-bl[l] != 1) cur = f[bl[l]+1][bl[r]-1]; for (int i=l; i<=bnd[bl[l]]; ++i) t[a[i]] = g[bl[r]-1][a[i]] - g[bl[l]][a[i]]; for (int i=bst[bl[r]]; i<=r; ++i) t[a[i]] = g[bl[r]-1][a[i]] - g[bl[l]][a[i]]; for (int i=l; i<=bnd[bl[l]]; ++i) { int x = a[i]; ++t[x]; if(t[x]&1) { if(t[x] == 1); else --cur; } else ++cur; } for (int i=bst[bl[r]]; i<=r; ++i) { int x = a[i]; ++t[x]; if(t[x]&1) { if(t[x] == 1); else --cur; } else ++cur; } printf("%d\n", lst = cur); } return 0; }
O(n根號nlogn)
# include <stdio.h> # include <string.h> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 1e5 + 10, N = 320, BLOCK = 350; const int mod = 1e9+7; # define RG register # define ST static int n, C, q, B; int a[M], bl[M]; int bst[N], bnd[N]; int t[M], tt[M], tn=0; int f[N][N]; int g[N][M]; // 1..i block j appear ? time inline void prepare(int x) { int cur = 0, tem = x; for (int i=bst[x]; i<=n; ++i) { ++t[a[i]]; if(t[a[i]]&1) { if(t[a[i]] == 1); else --cur; } else ++cur; if(bnd[tem] == i) { f[x][tem] = cur; ++tem; } } memset(t, 0, sizeof t); } int main() { scanf("%d%d%d", &n, &C, &q); for (int i=1; i<=n; ++i) { scanf("%d", a+i); bl[i] = (i-1)/BLOCK+1; } B = bl[n]; for (int i=1; i<=B; ++i) bst[i] = (i-1)*BLOCK+1, bnd[i] = min(n, i*BLOCK); for (int i=1; i<=B; ++i) prepare(i); for (int i=1; i<=n; ++i) g[bl[i]][a[i]]++; for (int i=1; i<=B; ++i) for (int j=1; j<=C; ++j) g[i][j] += g[i-1][j]; int l, r, lst=0; while(q--) { scanf("%d%d", &l, &r); l = (l+lst)%n+1, r = (r+lst)%n+1; if(l>r) swap(l, r); // printf("%d %d\n", l, r); if(bl[l] == bl[r]) { int cur = 0; for (int i=l; i<=r; ++i) { ++t[a[i]]; if(t[a[i]]&1) { if(t[a[i]] == 1); else --cur; } else ++cur; } printf("%d\n", lst = cur); for (int i=l; i<=r; ++i) --t[a[i]]; continue; } tn = 0; int cur = 0; if(bl[r]-bl[l] != 1) cur = f[bl[l]+1][bl[r]-1]; for (int i=l; i<=bnd[bl[l]]; ++i) tt[++tn] = a[i]; for (int i=bst[bl[r]]; i<=r; ++i) tt[++tn] = a[i]; sort(tt+1, tt+tn+1); // for (int i=1; i<=tn; ++i) printf("%d ", tt[i]); // puts("\n====="); for (int i=1; i<=tn; ++i) { int x = tt[i]; if(tt[i] != tt[i-1]) t[x] = g[bl[r]-1][x]-g[bl[l]][x]; ++t[x]; if(t[x]&1) { if(t[x] == 1); else --cur; } else ++cur; } printf("%d\n", lst = cur); for (int i=1; i<=tn; ++i) t[tt[i]] = 0; } return 0; }View Code
bzoj2821 作詩(Poetize)