首页 > 代码库 > cf196D:The Next Good String

cf196D:The Next Good String

给你一个整数m 和一个字符串s

输出一个字符串,使得这个字符串的字典序大于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;
}