0%

回文子串Manacher算法模板

r[i]是处理后每个字符的回文半径
r[i]-1即为处理前回文子串长度
P3805 【模板】manacher算法

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
#include<iostream>
#include<cstdio>
using namespace std;
const int P=19930726;
typedef long long LL;
char str[2000005];
int r[2000005],a[1000005];
LL sum[1000005];
int n,len;
LL k,ans=1;
void fast_pow(LL base,LL x) {
base%=P;
while (x>0) {
if (x&1) ans=ans*base%P;
base=base*base%P;
x>>=1;
}
}
void read() {
char ch;
len=1;str[1]='#';
while (ch<'a'||ch>'z') ch=getchar();
while (ch<='z'&&ch>='a') {
str[++len]=ch;
str[++len]='#';//避免奇偶性讨论
ch=getchar();
}
str[0]='$';str[len+1]='@';//防止下标越界
}
void manacher() {
int p=0,mx=0;
for (int i=1;i<=len;i++) {
if (mx>i) r[i]=min(r[2*p-i],mx-i);
else r[i]=1;
while (str[i+r[i]]==str[i-r[i]]) r[i]++;
if (i+r[i]>mx) p=i,mx=i+r[i];
}
}
int main() {
scanf("%d%lld",&n,&k);
read();
manacher();
for (int i=2;i<len;i+=2) a[1]++,a[r[i]]--;
for (int i=1;i<=(len>>1);i++) sum[i]=sum[i-1]+a[i];
if (!(n&1)) n--;
for (int i=n;i>0;i-=2) {
if (!sum[i]) continue;
LL tmp=min(k,sum[i]);
fast_pow(i,tmp);
k-=tmp;
if (k<=0) break;
}
if (k>0) cout<<-1;
else printf("%lld",ans);
return 0;
}