[Codeforces Gym] 100162B Circle of Stones 结论+Hash

来源:互联网 发布:淘宝店铺导航设置 编辑:程序博客网 时间:2024/06/14 10:47

首先考虑链上的情况:

假设存在一条链且任意相邻两位都不相同,那么不存在长度为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 1000000007using 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_JUDGEfreopen("problemb.in","r",stdin);#endifint cas = 0;while (~scanf("%s",s+1)) { printf("Case %d: ",++cas); solve(); }return 0;}



0 0