1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| #include <cstdio> #include <cstring> #include <algorithm> using namespace std; template <class Type> void read (Type &x) { char c; bool flag = false; while ((c = getchar()) < '0' || c > '9') if (c == '-') flag = true; x = c - '0'; while ((c = getchar()) >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0'; if (flag) x = ~x + 1; } template <class Type, class ...Rest> void read (Type &x, Rest &...y) { read(x), read(y...); } template <class Type> void write (Type x) { if (x < 0) putchar('-'), x = ~x + 1; if (x > 9) write(x / 10); putchar('0' + x % 10); } typedef long long L; const int N = (1 << 20) + 10, M = 27; char str[N]; bool g[2][M]; int n, z[N], f[2], h[M]; void init () { z[0] = 0; for (int i = 1, t = 0; i < n; ++i) { z[i] = 0; if (t + z[t] > i) z[i] = min(z[i - t], t + z[t] - i); while (i + z[i] < n && str[z[i]] == str[i + z[i]]) ++z[i]; if (i + z[i] > t + z[t]) t = i; } } void add (bool op, int c) { f[op] += (g[op][c] ^= 1) & 1 ? 1 : -1; } int main () { int T; read(T); while (T--) { scanf("%s", str); n = strlen(str); init(); for (int i = 0; i < n; ++i) add(1, str[i] - 'a'); int x = f[1]; L res = 0; for (int i = 0; i < n; ++i) { add(0, str[i] - 'a'), add(1, str[i] - 'a'); if (i > 0 && i < n - 1) { int t = z[i + 1] / (i + 1) + 1; if (t * (i + 1) == n) --t; int a = t >> 1, b = t - a; for (int j = 0; j <= x; ++j) res += (L)a * h[j]; for (int j = 0; j <= f[1]; ++j) res += (L)b * h[j]; } ++h[f[0]]; } write(res), puts(""); for (int i = n - 1; ~i; --i) --h[f[0]], add(0, str[i] - 'a'); } return 0; }
|