标签:子串 Hash ybtoj 样例 mid 测试用例 长度 回文
题意
题目描述
如果一个字符串正着读和倒着读是一样的,则称它是回文的。
给定一个长度为 N 的字符串 S,求他的最长回文子串的长度是多少。
输入格式
输入将包含最多 30 个测试用例,每个测试用例占一行,以最多 106 个小写字符的形式给出。
一个以字符串
END
(不包括引号)开头的行表示输入终止。输出格式
对于输入中的每个测试用例,输出测试用例编号和最大回文子串的长度(参考样例格式)。每个输出占一行。
样例
样例输入
abcbabcbabcba abacacbaaaab END
样例输出
Case 1: 13 Case 2: 6
题解
回文串还是经常遇见的一种题,所以第一时间想到:答案满足单调性所以二分长度,check函数里O(N)判断是否有长度为 mid 的回文串
有几个需要注意的点(我一开始没想到的):
- 回文串要分奇回文和偶回文讨论
- 存下反串和原串是对称的,写check的时候要注意一下
代码
回文子串
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int INF = 0x3f3f3f3f,N = 1e6+10,mod = 1e9+7,base = 233;
ll mi[N<<1],sum[N<<1];
int len,cnt;
char s[N<<1];
void init()
{
mi[0]=1;
for(int i=1;i<=len<<1;i++)
{
sum[i]=sum[i-1]*base+s[i]-'a'+1,sum[i]%=mod;
mi[i]=mi[i-1]*base,mi[i]%=mod;
}
}
inline ll Hash(int l,int r)
{
return (sum[r]-sum[l-1]*mi[r-l+1]%mod+mod)%mod;
}
inline bool check1(int mid)
{
for(int i=mid+1;i+mid<=len;i++)
if(Hash(i-mid,i+mid)==Hash(len*2-(i+mid)+1,len*2-(i-mid)+1))
{
//printf("[%d,%d]==[%d,%d]\n",i-mid,i+mid,len*2-(i+mid)+1,len*2-(i-mid)+1);
return true;
}
return false;
}
inline bool check2(int mid)
{
for(int i=mid;i+mid<=len;i++)
if(Hash(i-mid+1,i+mid)==Hash(len*2-(i+mid)+1,len*2-(i-mid+1)+1))
{
//printf("[%d,%d]==[%d,%d]\n",i-mid,i+mid,len*2-(i+mid)+1,len*2-(i-mid)+1);
return true;
}
return false;
}
int main()
{
while(1)
{
cnt++;
scanf("%s",s+1);
if(s[1]=='E'&&s[2]=='N'&&s[3]=='D') break;
len=strlen(s+1);
for(int i=1;i<=len;i++) s[i+len]=s[len-i+1];//在S末尾把反串存下来
init();
int l=0,r=len,ans1=0,ans2=0;
while(l<r)//奇回文
{
int mid=(l+r+1)>>1;
if(check1(mid)) l=mid;
else r=mid-1;
}
ans1=(l<<1)+1;
l=0,r=len;
while(l<r)//偶回文
{
int mid=(l+r+1)>>1;
if(check2(mid)) l=mid;
else r=mid-1;
}
ans2=(l<<1);
printf("Case %d: %d\n",cnt,max(ans1,ans2));
}
return 0;
}
标签:子串,Hash,ybtoj,样例,mid,测试用例,长度,回文 来源: https://www.cnblogs.com/conprour/p/15232182.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。