一、题目
二、解法
求前 k k k大的奇数回文子串,我们先跑一遍马拉车,然后差分算出每个长度的回文串,快速幂就可做了。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int M = 2000005;
const int MOD = 19930726;
#define ll long long
#define int long long
int read()
{
int x=0,flag=1;char c;
while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*flag;
}
int n,k,l[M],cnt[M];char s[M],t[M];
ll qkpow(ll a,int b)
{
ll res=1;
while(b>0)
{
if(b&1) res=res*a%MOD;
a=a*a%MOD;
b>>=1;
}
return res;
}
signed main()
{
n=read();k=read();
scanf("%s",s);
for(int i=0;i<n;i++)
{
t[2*i+1]=s[i];
t[2*i]='#';
}
t[2*n]='#';
n=2*n+1;
int c=0,r=0,ans=0;
for(int i=0;i<n;i++)
{
l[i]=r>i?min(l[2*c-i],r-i+1):1;
while(i+l[i]<n && i-l[i]>=0 && t[i+l[i]]==t[i-l[i]])
l[i]++;
if(i+l[i]>r)
{
r=i+l[i]-1;
c=i;
}
ans=max(ans,l[i]);
}
for(int i=1;i<n;i+=2)
{
cnt[1]++;cnt[l[i]+1]--;
}
for(int i=3;i<n;i+=2)
{
cnt[i]+=cnt[i-2];
}
ll mul=1;
for(int i=n-2;i>0;i-=2)
{
if(k>=cnt[i])
{
mul=mul*qkpow(i,cnt[i])%MOD;
k-=cnt[i];
}
else
{
mul=mul*qkpow(i,k)%MOD;
k=0;
break;
}
}
if(k) puts("-1");
else printf("%lld\n",mul);
}