题意:求每个前缀是否是ABABA 的形式。(其中A有k+1个,B有k个,AB均可为空)
对于一个前缀字符串i:
令S=AB
则可看成:SSSSA。
若满足S的个数为k,则满足题意。
对于前缀字符串i:其最小循环节e长度为:i-nxt[i], 改字符串可以看做:eeeex
如果若干个e拼凑成一个S,使得S的数量为k,则满足题意。
即:
(下取整)构成:AB AB AB AB A
或者当i%e==0时,
,此时B为空。
第二种情况很好求。
关键是第一种:
我们知道 [x](下取整)=k 则有: k <= x < k+1
则有:
即:
则可O1处理这个判断:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e6+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int n,k;
char s[M];
int nxt[M];
bool ck(int i,int e)//e是最小循环节的长度
{
//SSSA
//k+1个A,k个B
//1:i/e = j * k = > k<= i/(j*e) < k+1
//= > i/(e*(k+1)) < j <=i/(e*k)
if(i/e/k>i/e/(k+1)) return true;
//2: A='0',即 i%e==0, 且 i/e = j*k
if(i%e==0&&(i/e%k==0||i/e%(k+1)==0))return true;
return false;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>k;
cin>>s+1;
nxt[1]=0;
for(int i=2,j=0;i<=n;i++)
{
while(j&&s[i]!=s[j+1])j=nxt[j];
if(s[i]==s[j+1])j++;
nxt[i]=j;
}
//ABABA 令S=AB SSSA
//对于前缀i,len=i-ntx[i], 则前缀i可以表示为:SSSA ,其中S的长度为len,A是S的前缀 (nxt[i]的性质)
for(int i=1;i<=n;i++)
{
// cout<<i<<" - "<<i-nxt[i]<<" "<<ck(i,i-nxt[i])<<endl;
cout<<ck(i,i-nxt[i]);
}
// cout<<ck(i,i-nxt[i]);
cout<<endl;
return 0;
}