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

首先考虑链上的情况:

假设存在一条链且任意相邻两位都不相同,那么不存在长度为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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值