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 }
原文地址:https://www.cnblogs.com/tellmewtf/p/2863539.html