首先考虑链上的情况:
假设存在一条链且任意相邻两位都不相同,那么不存在长度为l的合法链的充分必要条件是所有相距为l的字符都相同。
若所有相距为l的字符串的字符都相同的充分必要条件是字符串s1<1,n-l>和字符串s2<l,n>完全相同。
字符哈希判断即可。
环上:
三倍长拆环,每次寻找一条任意相邻两位都不相同的链,按照上面结论哈希即可。
Notice:
1、本题不需要开模数大小的数组,所以模数可以取大一点。
2、主要hash相乘的时候可能会爆int
3、模数是1e8+7被卡了(?),好像要1e9+7才能过
#include <iostream>
#include <cstdio>
#include <cstring>
#define lhr 27LL
#define N 3000050
#define mod 1000000007
using namespace std;
typedef long long LL;
int ans[N],n;
LL sum[N],e[N];
char s[N];
inline LL dec(LL p1,LL p2) { return p1-p2<0 ? p1-p2+mod : p1-p2; }
inline bool check(int l1,int r1,int l2,int r2) {
LL p1 = dec( sum[r1] , sum[l1-1] * e[r1-l1+1] % mod );
LL p2 = dec( sum[r2] , sum[l2-1] * e[r2-l2+1] % mod );
return p1 == p2;
}
void solve() {
//memset(ans,0,sizeof(ans));
//memset(sum,0,sizeof(sum));
n = strlen(s+1);
for (int i=1;i<=n;i++) ans[i] = 0;
for (int i=1;i<=n;i++) s[n+i] = s[2*n+i] = s[i];
for (int i=1;i<=3*n;i++) sum[i] = ( sum[i-1]*lhr+(s[i]-'a'+1) ) % mod;
e[0]=1; for (int i=1;i<=3*n;i++) e[i] = (e[i-1]*lhr) % mod;
int l = 1 , r = -1;
for (;l<=3*n;l=r+1) {
while (l+1<=3*n && s[l] == s[l+1]) l++;
if (l == 3*n) break;
r = l + 1;
while (r+1<=3*n && s[r] != s[r+1]) r++;
for (int i=1;i<=min(r-l+1,n);i++)
if (!check(l,r-i+1,l+i-1,r)) ans[i] = 1;
}
for (int i=n;i>=2;i--) printf("%d",ans[i]); printf("1\n");
return ;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("problemb.in","r",stdin);
#endif
int cas = 0;
while (~scanf("%s",s+1)) { printf("Case %d: ",++cas); solve(); }
return 0;
}