| 12
 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;
 }
 
 |