zoukankan      html  css  js  c++  java
  • CF526D Om Nom and Necklace

    gate

    用时:反正挺久的

    给定长度为(n)的字符串和整数(k),问每个前缀能否拆成(ABABA)(B)可以为空,即(AAAAA))((k+1)(A))的形式。
    (AB)(S),则(A)(S)的前缀。
    问题转化为拆成(SSSSA)(SSSSS)
    (KMP),通过(fail)数组可以求出最小循环节长度为(n-f[n])
    字符串中共有(sum = n/(n-f[n]))个最小循环节。
    即,(S)的长度为(sum/k)(A)的长度为(sum\%k)(B)的长度为(sum/k-sum\%k)
    (n\%(n-f[n]) ot=0),即字符串不是恰好由(n-f[n])的循环组成的,形式为(SSSSA)
    则必须有(B)的长度(>0)
    否则若(n\%(n-f[n])=0),即可能为(SSSSS)
    则有(B)的长度(ge0)

    注意这里(KMP)的写法。
    code

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #define MogeKo qwq
    using namespace std;
    
    const int maxn = 1e6+10;
    int n,k,f[maxn];
    char s[maxn];
    
    void getf() {
    	for(int i = 2,j = 0; i <= n; i++) {
    		while(j && s[i] != s[j+1]) j = f[j];
    		if(s[i] == s[j+1]) j++;
    		f[i] = j;
    	}
    }
    
    int main() {
    	scanf("%d%d",&n,&k);
    	scanf("%s",s+1);
    	getf();
    	for(int i = 1; i <= n; i++) {
    		int sum = i/(i-f[i]);
    		if(i%(i-f[i]) != 0)
    			if(sum/k > sum%k) printf("1");
    			else printf("0");
    		else if(sum/k >= sum%k) printf("1");
    			 else printf("0");
    	}
    	return 0;
    }
    
  • 相关阅读:
    软件工程第一次结对作业
    软件工程第二次作业
    vue之vuex
    ceshi
    第3次 结构与部分
    第二次作业
    获得领跑衫感言
    期末总结
    第十四,十五周作业
    第七周作业
  • 原文地址:https://www.cnblogs.com/mogeko/p/13222171.html
Copyright © 2011-2022 走看看