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
| #include <cstdio> #include <algorithm> using namespace std; typedef long long LL; const int N = 4e6 + 10, mod = 51123987; char s[N]; int n, d[N], f[N], g[N]; void init() { s[n++] = '$', s[n++] = '#'; char c = getchar(); while (c < 'a' || c > 'z') c = getchar(); while (c >= 'a' && c <= 'z') s[n++] = c, s[n++] = '#', c = getchar(); s[n++] = '^'; } int main() { scanf("%*d"); init(); for (int i = 0, l = 0, r = -1; i < n; i++) { int k = i <= r ? min(d[l + r - i], r - i + 1) : 1; while (i - k >= 0 && i + k < n && s[i - k] == s[i + k]) ++k; d[i] = k; if (i + k - 1 > r) l = i - k + 1, r = i + k - 1; } for (int i = 0; i < n; ++i) if (d[i] > 1) ++f[i + 1 >> 1], --f[i + d[i] + 1 >> 1], ++g[i >> 1], --g[i - d[i] >> 1]; n = n - 3 >> 1; for (int i = 2; i <= n; ++i) f[i] += f[i - 1]; for (int i = n - 1; i; --i) g[i] += g[i + 1]; for (int i = 2; i <= n; ++i) (f[i] += f[i - 1]) %= mod; int res = f[n] * (f[n] - 1ll) / 2 % mod; for (int i = 1; i < n; ++i) res = (res - (LL)f[i] * g[i + 1]) % mod; printf("%d", (res + mod) % mod); return 0; }
|