m
a
n
a
c
h
e
r
manacher
manacher 求每个奇回文串的数量,用一个桶装起来。
桶的乘积用快速幂 。
m
a
n
a
c
h
e
r
manacher
manacher 只是求出来每个中心点最大能够是多长的回文串,所以对于某一个长度的回文串,对应长度桶里数量并不一定是该长度回文串的准确数量,如:
m
a
n
a
c
h
e
r
manacher
manacher 求出
m
p
[
7
]
=
1
mp[7]=1
mp[7]=1
m
p
[
5
]
=
1
mp[5]=1
mp[5]=1 ,
m
p
[
5
]
mp[5]
mp[5] 真的就只等于
1
1
1 吗?否,上一个
7
7
7 长度的回文串也包含有一个
5
5
5 。所以我们从最长的回文串向下计数这样就能长向短累计了。 Think Twice, Code Once
#include<bits/stdc++.h>#defineilinline#definegetgetchar#defineputputchar#defineisisdigit#definereregister#defineintlonglong#definedfor(i,a,b)for(re int i=a;i<=b;++i)#definedforr(i,a,b)for(re int i=a;i>=b;--i)#definedforn(i,a,b)for(re int i=a;i<=b;++i,put(10))#definemem(a,b)memset(a,b,sizeof a)#definememc(a,b)memcpy(a,b,sizeof a)#definepr114514191981#definegg(a) cout<<a,put(32)#defineINF0x7fffffff#definett(x) cout<<x<<'\n'#definelsi<<1#definersi<<1|1#definela(r) tr[r].ch[0]#definera(r) tr[r].ch[1]#definelowbit(x)(x&-x)usingnamespace std;typedefunsignedint ull;intread(void){
re int x=0,f=1;re char c=get();while(!is(c))(f=c==45?-1:1),c=get();while(is(c)) x=(x<<1)+(x<<3)+(c^48),c=get();return x*f;}voidwrite(int x){if(x<0) x=-x,put(45);if(x>9)write(x/10);put((x%10)^48);}#definewriteln(a)write(a),put(10)#definewritesp(a)write(a),put(32)#definewritessp(a)put(32),write(a)constint N=2e6+10,M=3e4+10,SN=1e4+10,mod=19930726;int n,k,ans=1,cnt,len,maxx,p[N];char s[N],t[N];
unordered_map<int,int> mp;intqpow(int base ,int b){
re int ans1=1;while(b){if(b&1) ans1=(ans1*base)%mod;
base=(base*base)%mod;
b>>=1;}return ans1;}signedmain(){
n=read(),k=read();scanf("%s",s+1);
t[++len]='!',t[++len]='#';dfor(i,1,n) t[++len]=s[i],t[++len]='#';
t[++len]='%';
re int mid=0,r=0;dfor(i,2,len-1){if(i<=r) p[i]=min(p[(mid<<1)-i],r-i+1);else p[i]=1;while(t[i+p[i]]==t[i-p[i]])++p[i];if(i+p[i]>r) r=i+p[i]-1,mid=i;if((p[i]-1)&1)++mp[p[i]-1],maxx=max(maxx,p[i]-1);}while(maxx>0){
cnt+=mp[maxx];if(cnt<=k) ans=(ans*qpow(maxx,cnt))%mod,k-=cnt;else{ans=(ans*qpow(maxx,k))%mod,k-=cnt;break;}
maxx-=2;}
k>0?write(-1):write(ans);return0;}