【校内模拟】小B的环(KMP)

简要题意:

给一个字符环,长度为 n n n ,请你对 ∀ k ∈ [ 0 , n − 1 ] \forall k \in [0,n-1] k[0,n1],回答,能否删去一个长度为 k k k 的子串,使得剩下部分首尾相接之后,任何相邻的两个位置字符不同。

n ≤ 5 e 6 n\leq 5e6 n5e6


题解:

考虑剩什么而不是删什么。

容易发现我们把存在相邻字符相同的位置拿出来,把这些位置之间的串拿出来,判断剩哪些子串合法即可。显然是周期以外的都行。

注意,如果没有任何相邻位置的字符相同,我们需要计算这个环的周期,需要将环复制一次才行。

计算周期直接KMP即可。


代码:

#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const

namespace IO{
	inline char gc(){
		static cs int Rlen=1<<22|1;static char buf[Rlen],*p1,*p2;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++; 
	}inline int get_s(char *s){
		char c;while(isspace(c=gc())&&c!=EOF);if(c==EOF)return -1;
		int len=0;while(s[len++]=c,!isspace(c=gc())&&c!=EOF);
		s[len]='\0';return len;
	}
	char obuf[10000007],*oh=obuf;
	struct obuf_flusher{~obuf_flusher(){fwrite(obuf,1,oh-obuf,stdout);}}Flusher;
}using namespace IO;

using std::cerr;
using std::cout;

cs int N=5e6+7;

int n;
char s[N<<1|1];
bool ans[N];int ps[N],ct;
int nx[N<<1|1];
void solve(char *a,int len){
	for(int re i=2,j=0;i<=len;++i){
		while(j&&a[i]!=a[j+1])j=nx[j];
		if(a[i]==a[j+1])++j;nx[i]=j;
	}int now=len,las=1;
	while(now){
		for(int re i=las;i<=len-nx[now];++i)if(n>i)ans[n-i]=true;
		las=len-nx[now]+2;now=nx[now];
	}
}

void Main(){
	while((n=get_s(s+1))!=-1){
		if(n==1){*oh++='0';*oh++='\n';continue;}
		memset(ans,0,sizeof(bool)*n);
		for(int re i=n+1;i<=2*n;++i)s[i]=s[i-n];
		ct=0;for(int re i=1;i<=n;++i)if(s[i]==s[i+1])ps[++ct]=i;
		if(ct)*oh++='0',ps[++ct]=ps[1]+n;else *oh++='1';
		for(int re i=0;i<ct;++i)
			solve(s+ps[i],ps[i+1]-ps[i]);
		if(!ct)solve(s,n<<1);
		for(int re i=1;i<n-1;++i)*oh++=ans[i]+'0';
		*oh++='0';*oh++='\n';
	}
}

inline void file(){
#ifndef ONLINE_JUDGE
	freopen("loop.in","r",stdin);
	freopen("loop.out","w",stdout);
#endif
}
signed main(){file();Main();return 0;}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值