【马拉车manacher】奇长回文(2022.5.21)
上题目!
题目
3.1 题目描述
给定一个长为 L 的仅含小写字母的字符串,需要在其奇数长度的回文子串中找到最长的 k 个,并且输出它们长度的乘积对19961202 取模的值,若奇数长度的回文子串不足 k 个则输出-1 。
3.2 输入格式
第一行两个整数L, k,如题意所述;
接下来一行为一个长为 L 的字符串。
3.3 输出格式
输出一行一个整数,表示答案。
3.4 样例输入
5 3
ababa
3.5 样例输出
45
3 .6 样例解释
奇数长度的回文子串有:ababa, aba, aba, bab, a, a, a, b, b,最长的三个长度分别为 5, 3, 3,故乘积为 533=45
3 .7 数据范围与约定
对于前20%的数据,L, k≤100;
对于另外20%的数据,k=1;
对于100%的数据,1≤L≤106, 1≤k≤1012
解思
马拉车裸题,甚至都不需要在字符中间加&,跑出以每个点为中心的最大奇长回文串后从大往小累加计算,再跑快速幂即可
long long乘爆的人就是屑
代码如下:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
int f=1,j=0;char w=getchar();
while(w>'9'|w<'0'){
if(w=='-')f=-1;
w=getchar();
}
while(w>='0'&&w<='9'){
j=(j<<3)+(j<<1)+w-'0';
w=getchar();
}
return f*j;
}
const int N=1000010,mod=19961202;
char s[N];
int tong[N],n,k,f[N],sum,maxn,ans=1;
int mi(int x,int y){
int nown=x,ansn=1;
while(y>0){
if(y&1)ansn=ansn*nown%mod;
nown=nown*nown%mod;
y/=2;
}
return ansn;
}
signed main(){
//freopen("odd.in","r",stdin);
//freopen("odd.out","w",stdout);
n=read();k=read();
scanf("%s",s+1);
int r=0,mid=0;
for(int i=1;i<=n;i++){
if(i>r){
int len=0;
while(i-len-1>0&&i+len+1<=n&&s[i-len-1]==s[i+len+1])len++;
f[i]=len;
mid=i;r=i+len;
}
else{
int len=f[mid*2-i];
if(len<r-i)f[i]=len;
else{
len=min(r-i,len);
while(i-len-1>0&&i+len+1<=n&&s[i-len-1]==s[i+len+1])len++;
if(i+len>r){
mid=i;
r=i+len;
}
f[i]=len;
}
}
tong[f[i]]++;
maxn=max(f[i],maxn);
sum+=f[i]+1;
}
if(sum<k){
printf("-1");
return 0;
}
int nown=0;
for(int i=maxn;i>=1&&k!=0;i--){
nown+=tong[i];
if(nown>=k){
ans=ans*mi(i*2+1,k)%mod;
break;
}
else{
k-=nown;
ans=ans*mi(i*2+1,nown)%mod;
}
}
printf("%d",ans);
return 0;
}
/*
5 3
ababa
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】