题目:BZOJ2160.
题目大意:给定一个字符串
S
S
S,求它所有长度为奇数的回文子串中,前
k
k
k小的长度乘积.若数量超过
k
k
k输出
−
1
-1
−1.
1
≤
∣
S
∣
≤
1
0
6
,
1
≤
k
≤
1
0
1
2
1\leq |S|\leq 10^6,1\leq k\leq 10^12
1≤∣S∣≤106,1≤k≤1012.
一看就是道manacher裸题,由于长度要求为奇数,所以就不需要在字符串中间插入奇奇怪怪的字符啦,只需要在两边插入不一样的字符就可以了.
我们再设一个数组 c n t [ i ] cnt[i] cnt[i]表示长度为 i i i的回文子串有多少个,那么每得到一个新的最长回文子串长度 p a l [ i ] pal[i] pal[i]我们就可以将 1 1 1~ p a l [ i ] pal[i] pal[i]的所有 c n t cnt cnt值都加 1 1 1,但是这样太慢了所以我们差分一下.
最后我们从 1 1 1开始枚举,每次加 2 2 2.当枚举到i时得到的贡献为 i c n t [ i ] i^{cnt[i]} icnt[i],快速幂搞一下就可以了.
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define Abigail inline void
typedef long long LL;
const int N=1000000;
const LL mod=19930726;
int pal[N+9];
void manacher(char *s,int len){
s[len+1]='#';
int p=0,r=0;
pal[0]=1;
for (int i=1;i<=len;++i){
pal[i]=i<r?min(pal[2*p-i],r-i):1;
while (s[i+pal[i]]==s[i-pal[i]]) ++pal[i];
if (i+pal[i]>r) r=i+pal[i],p=i;
}
}
int cnt[N+9];
LL power(LL a,LL k){
LL s=1;
for (;k;k>>=1,a=a*a%mod)
if (k&1) s=s*a%mod;
return s;
}
char c[N+9];
int n;
LL k,ans=1;
void js(){
for (int i=1;i<=n;++i)
++cnt[1],--cnt[pal[i]<<1];
for (int i=1;i<=n;++i)
cnt[i]+=cnt[i-1];
for (int i=n;i>=1;--i){
if (i&1^1) continue;
if (cnt[i]>=k){
ans=ans*power(LL(i),k)%mod;k=0;
break;
}else ans=ans*power(LL(i),LL(cnt[i]))%mod,k-=LL(cnt[i]);
}
if (k) ans=-1LL;
}
Abigail into(){
scanf("%d%lld",&n,&k);
scanf("%s",c+1);
}
Abigail work(){
manacher(c,n);
js();
}
Abigail outo(){
printf("%lld",ans);
}
int main(){
into();
work();
outo();
return 0;
}