CodeForces 526D Om Nom and Necklace

Om Nom and Necklace

题意:

询问每个前缀是否能构成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, 

扫描二维码关注公众号,回复: 6250470 查看本文章

现在每个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;
}
View Code

猜你喜欢

转载自www.cnblogs.com/MingSD/p/10878827.html