看到回文串,就想到了manacher。而且这道题只用求长度为奇数的回文串,所以不用添加字符,在原回文串上跑一边即可。
需要注意的是,如果一个回文串的半径是r,那么这个回文串同时也包含了r - 1, r - 2,……1的回文串,因为r表示的是以 i 为回文中心的最长的回文串。于是我们开一个桶,记录回文半径长度为 i 的回文串有多少个,用前缀和的思想,差分维护区间加1。最后倒着扫一边,快速幂加速乘法。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 1e6 + 5; 21 const ll mod = 19930726; 22 inline ll read() 23 { 24 ll ans = 0; 25 char ch = getchar(), last = ' '; 26 while(!isdigit(ch)) {last = ch; ch = getchar();} 27 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 28 if(last == '-') ans = -ans; 29 return ans; 30 } 31 inline void write(ll x) 32 { 33 if(x < 0) x = -x, putchar('-'); 34 if(x >= 10) write(x / 10); 35 putchar(x % 10 + '0'); 36 } 37 38 int n; 39 ll k; 40 char s[maxn]; 41 int r[maxn]; 42 43 void manacher() 44 { 45 s[0] = '@'; s[n + 1] = '$'; 46 int mx = 0, id; 47 for(int i = 1; i <= n; ++i) 48 { 49 if(i < mx) r[i] = min(r[(id << 1) - i], mx - i); 50 else r[i] = 1; 51 while(s[i - r[i]] == s[i + r[i]]) r[i]++; 52 if(i + r[i] > mx) mx = i + r[i], id = i; 53 } 54 } 55 56 ll dif[maxn]; 57 ll ans = 1; 58 59 ll quickpow(ll a, ll b) 60 { 61 a %= mod; 62 ll ret = 1; 63 while(b) 64 { 65 if(b & 1) ret = ret * a % mod; 66 a = a * a % mod; b >>= 1; 67 } 68 return ret; 69 } 70 71 int main() 72 { 73 n = read(); k = read(); scanf("%s", s + 1); 74 manacher(); 75 for(int i = 1; i <= n; ++i) dif[1]++, dif[r[i] + 1]--; 76 for(int i = 1; i <= n; ++i) dif[i] = dif[i - 1] + dif[i]; 77 for(int i = (n + 1) >> 1; i; --i) 78 { 79 if(k - dif[i] > 0) 80 { 81 k -= dif[i]; 82 ans *= quickpow((i << 1) - 1, dif[i]); 83 ans %= mod; 84 } 85 else 86 { 87 ans *= quickpow((i << 1) - 1, k); 88 ans %= mod; 89 k = 0; break; 90 } 91 } 92 write(k ? -1 : ans); enter; 93 return 0; 94 }