BZOJ2821 作诗
黄四郎:三天之后,一定让县长过了作诗!
张麻子:汤师爷,他是原来过不了作诗的你现在也过不了作诗,你给翻译翻译,什么叫常数?
张麻子:翻译翻译,什么叫常数!
汤师爷:这还用翻译?都说了
张麻子:我让你翻译给我听,什么叫常数!
汤师爷:不用翻译,就是常数啊难道你听不懂什么叫常数?
张麻子:我就想让你翻译翻译,什么叫常数!
汤师爷:常数嘛!
张麻子:翻译出来给我听!什么他妈的叫常数!什么他妈的叫他妈的常数!
汤师爷:什么他妈的叫常数啊?
黄四郎:常数就是三天之后,你依然过不了作诗!明白了吗?
汤师爷:这就是常数啊!
什么他妈的叫他妈的常数
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <iostream> 5 using namespace std; 6 const int N = 101000, M = 400; 7 int n, m, a[N], c[N], bg[N], en[N], col, st[M], ed[M], l, p, b[N], d[M][M], v[N], q[N]; 8 void prework () 9 { 10 for (int i = 1; i <= n; i ++) c[a[i]] ++; 11 for (int i = 1, tot = 0; i <= col; i ++) bg[i] = tot + 1, en[i] = tot + c[i], tot += c[i]; 12 memset (c, 0, sizeof c); 13 for (int i = 1; i <= n; i ++) b[bg[a[i]] + c[a[i]]] = i, c[a[i]] ++; 14 p = (int)sqrt (n * 1.0); l = n / p; 15 for (int i = 1; i <= p; i ++) 16 st[i] = (i - 1) * l + 1, ed[i] = i * l; 17 if (ed[p] < n) st[p + 1] = p * l + 1, ed[p + 1] = n, p ++; 18 for (int i = 1, now; i <= p; i ++) 19 { 20 memset (c, 0, sizeof c);now = 0; 21 for (int j = i; j <= p; j ++) 22 { 23 for (int k = st[j]; k <= ed[j]; k ++) 24 { 25 c[a[k]] ++; 26 if (c[a[k]] == 1) continue; 27 if ((c[a[k]] & 1) == 1) now --; 28 else if ((c[a[k]] & 1) == 0) now ++; 29 } 30 d[i][j] = now; 31 //printf ("%d ", now); 32 } 33 } 34 } 35 inline int calc (int x, int st, int ed) 36 { 37 int l = bg[x], r = en[x] + 1, m; 38 while (l < r - 1) 39 { 40 m = l + r >> 1; 41 if (b[m] <= st) l = m; 42 else r = m; 43 } 44 if (b[l] < st) 45 l ++; 46 int t = l; 47 l = bg[x], r = en[x] + 1; 48 while (l < r - 1) 49 { 50 m = l + r >> 1; 51 if (b[m] <= ed) l = m; 52 else r = m; 53 } 54 if (b[l] > ed) 55 l --; 56 return l - t + 1; 57 } 58 int main () 59 { 60 freopen ("a.in", "r", stdin); 61 freopen ("a.out", "w", stdout); 62 scanf ("%d%d%d", &n, &col, &m); 63 for (int i = 1; i <= n; i ++) 64 scanf ("%d", &a[i]); 65 prework (); 66 for (int i = 1, L, R, ans (0), l, r, cnt; i <= m; i ++) 67 { 68 scanf ("%d%d", &l, &r); 69 l = (l + ans) % n + 1; 70 r = (r + ans) % n + 1; 71 if (l > r) 72 swap (l, r); 73 for (L = 1; L <= p; L ++) if (st[L] >= l) break; 74 for (R = p; R >= 1; R --) if (ed[R] <= r) break; 75 if (L <= R) 76 { 77 ans = d[L][R];cnt = 0; 78 for (int j = l; j <= st[L] - 1; j ++) 79 if (v[a[j]] != i) v[a[j]] = i, c[a[j]] = 1, q[++ cnt] = a[j]; 80 else c[a[j]] ++; 81 for (int j = ed[R] + 1; j <= r; j ++) 82 if (v[a[j]] != i) v[a[j]] = i, c[a[j]] = 1, q[++ cnt] = a[j]; 83 else c[a[j]] ++; 84 for (int i = 1; i <= cnt; i ++) 85 { 86 int tmp = calc (q[i], st[L], ed[R]); 87 if (tmp == 0 && c[q[i]] && (c[q[i]] & 1) == 0) ans ++; 88 else if (tmp && c[q[i]] && (tmp & 1) == 0 && (c[q[i]] & 1) == 1) ans --; 89 else if (tmp && c[q[i]] && (tmp & 1) == 1 && (c[q[i]] & 1) == 1) ans ++; 90 } 91 } 92 else 93 { 94 ans = 0; 95 for (int j = l; j <= r; j ++) 96 if (v[a[j]] != i) v[a[j]] = i, c[a[j]] = 1; 97 else { 98 c[a[j]] ++; 99 if ((c[a[j]] & 1) == 1) ans --; 100 else ans ++; 101 } 102 } 103 printf ("%d\n", ans); 104 } 105 return 0; 106 }