题意:
询问每个前缀是否能构成A + B + A + ...+ B + A这个形式。
题解:
首先要明白的是KMP求最小循环节,然后算出前面有多少个重复的串。
一个串有2种构成方式:
1. SSSSSS, 及这个串刚好是全由S构成的的,一共z个S。 需要明白的是,因为有k个AB, 所以z%k之后,就是剩下A的个数, 然后判断一下B的长度是不是>=0的,因为B可以为空。 B的长度计算为 Z / k - Z % k > =0。
2. SSSSST,这个串是由Z个S组成的,剩下一个T,且T是S的一个前缀。 在这个地方,我们需要用B去占据A的串,或者分割B,使得A的串和最后的T相同,所以B的长度 Z / K - Z % k > 0.
在第2个样例中的第21个前缀
S = ababa , T = a,
现在每个B由2个S
也就是说 " " + SS + " " + SS + a
然后 我们可以吧第一个S的a都分给A。
最后的答案就是 a + baba S + a + babaS + a
在前面的过程中,我们将A的串尽可能的短,这样才能使得这个串合法性最大。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e6 + 100; char s[N]; int nt[N]; int n, k; int ans[N]; void getnext(){ int k = -1, j = 0; nt[0] = -1; while(j < n){ if(k == -1 || s[j] == s[k]) nt[++j] = ++k; else k = nt[k]; } } int Ac(){ scanf("%d%d", &n, &k); scanf("%s", s); getnext(); for(int i = 1; i <= n; ++i){ int len = i - nt[i]; if(i % len == 0){ int kk = i / len; if(kk/k >= kk%k) ans[i] = 1; } else { int kk = i / len; if(kk/k > kk%k) ans[i] = 1; } } for(int i = 1; i <= n; ++i) putchar('0' + ans[i]); return 0; } int main(){ Ac(); return 0; }