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