题目描述
对于两个串S1、S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同。例如串ababba和串abbaab是循环相同的。
给出一个长度为n的串S,求满足下面条件的最大的L:
1. L<=n/2
2. S的L前缀和S的L后缀是循环相同的。
输入
第一行一个正整数n (n<=1,000,000)。第二行n个小写英文字母,表示串S。
输出
一个整数,表示最大的L。
样例输入
ababbabababbaab
样例输出
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll h[1000010];
ll g[1000010];
ll base1[1000010];
ll base2[1000010];
char ch[1000010];
int mod=1e9+7;
int n;
int f[1000010];
int ans=0;
bool check(int x,int y,int l)
{
ll s1,s2,t1,t2;
s1=((h[x+l-1]-h[x-1]*base1[l])%mod+mod)%mod;
s2=((g[x+l-1]-g[x-1]*base2[l])%mod+mod)%mod;
t1=((h[y+l-1]-h[y-1]*base1[l])%mod+mod)%mod;
t2=((g[y+l-1]-g[y-1]*base2[l])%mod+mod)%mod;
if(s1==t1&&s2==t2)
{
return true;
}
return false;
}
int main()
{
scanf("%d",&n);
scanf("%s",ch+1);
base1[0]=1;
base2[0]=1;
for(int i=1;i<=n;i++)
{
base1[i]=base1[i-1]*233%mod;
base2[i]=base2[i-1]*2333%mod;
h[i]=(h[i-1]*233+(ch[i]-96))%mod;
g[i]=(g[i-1]*2333+(ch[i]-96))%mod;
}
for(int i=n/2;i>=1;i--)
{
f[i]=min(f[i+1]+2,(n-2*i)/2);
while(f[i]&&(!check(i+1,n-f[i]+1-i,f[i])))
{
f[i]--;
}
}
for(int i=1;i<=n/2;i++)
{
if(!check(1,n-i+1,i))
{
continue;
}
ans=max(ans,f[i]+i);
}
printf("%d",ans);
}
转载于:https://www.cnblogs.com/Khada-Jhin/p/9637166.html
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/101431.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...