输出一个字符串,使得这个字符串的字典序大于s(且是最小的字典序)且满足不存在长度大于等于m的回文子串
利用回文串的性质,只要修改当前某个字符后,前m个字符 和 前m+1个字符不为回文串,那么就可以继续构造,构造完后绝对不会产生大于m的回文子串
用哈希判断回文串
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 500000
#define mo 1000000007
const int h[27]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101};
const int pp=253;
typedef long long LL;
LL f1[N], f2[N], p[N], s1, s2;
int a[N], n, i, l;
char ch;
bool flag,flagt;
bool check(int i,int n)
{
if (i>=n)
{
s1=((f1[i]-f1[i-n] * p[n+1] % mo) * p[i-n+1] % mo + mo) % mo;
s2=((f2[i]-f2[i-n]) % mo + mo) % mo;
if (s1==s2) return false;
}
return true;
}
int add(int i)
{
while (i>=1 && a[i]==26) a[i--]=1;
if (i==0)
{
printf("Impossible");
flag=false;
return i;
}
a[i]++;
return i;
}
int main()
{
scanf("%d\n",&n);
scanf("%c",&ch);
while (ch>='a' && ch<='z')
{
a[++l]=ch - 'a' + 1;
scanf("%c",&ch);
}
flag=true;
i=l;
add(i);
p[0]=p[1]=1;
for (i=2; i<=l; i++)
p[i]=(p[i-1] * pp) % mo;
for (i=1; i<=n-1; i++)
f1[i]=(f1[i-1] * pp + h[a[i]]) % mo, f2[i]=(f2[i-1] + h[a[i]] * p[i]) % mo;
i=n; flagt=false;
while (i<=l)
{
f1[i]=(f1[i-1] * pp + h[a[i]]) % mo, f2[i]=(f2[i-1] + h[a[i]] * p[i]) % mo;
if (check(i, n) && check(i, n + 1))
{
i++;
if (flagt && i<=l) a[i]=1;
}
else i=add(i), flagt=true;
if (!flag) return 0;
}
for (i=1; i<=l; i++)
printf("%c",a[i]+96);
return 0;
}cf196D:The Next Good String,布布扣,bubuko.com
原文地址:http://blog.csdn.net/dream_epic/article/details/27213017