有一天,欧姆诺姆发现了一串长度为n的宝石串,上面有五颜六色的宝石。他决定摘取前面若干个宝石来做成一个漂亮的项链。
他对漂亮的项链是这样定义的,现在有一条项链S,当S=A+B+A+B+A+...+A+B+A的时候是漂亮的,这儿A,B是一些宝石串,“+”表示连接操作。S中有k+1个A和k个B组成。A和B可能是空串。
现在给出宝石串,问怎么切前几个才能得到一个漂亮的宝石项链。他切下来之后不会改变宝石的顺序。
样例解释:
在这个样例中前6个可以组成漂亮的串( A="", B="bca")。前7个也可以(A="b", B="ca")。
Input单组测试数据。 第一行有两个整数n, k (1≤n,k≤1 000 000),表示宝石串原始的长度和在上文中提到的参数k。 第二行有n个由小写字母组成的串,表示原始宝石串。Output输出一行有n个01组成的字符串。第i(1≤i≤n)个位置是1的时候表示前i个宝石可以组成漂亮的宝石项链。Sample Input
样例输入17 2bcabcabSample Output
样例输出10000011 满足ABABA..A或者ABAB...B的情况都可以切一下,第二种情况可以看做A = "",假如总串是acdebacdebacde,答案是00000000011111,第一处A = "",B = "acdeb",第二处A = "a",B = "cdeb",第三处A = "ac",B = "deb",第四处... 用kmp可以求出循环节,设循环的串为s,在第i个位置,只要满足两种情况就可以,需要选出k+1个A和k个B,第一种情况不能被s完全覆盖,会多出来一块,只要多出来的一块含有的s小于AB含有的s就可以,A < AB,对于第二种情况就是第一种情况的基础上满足等于, 如果是k+1个AB,完全可以把B看做空串,那就是k+1个A和k个空串了。 代码:
#include#include #include #include #include #include #include using namespace std;int nex[1000005],n,k;char s[1000005],ans[1000005];void getnex(char *t,int len){ nex[0] = -1; int i = 0,j = -1; while(i < len) { if(j == -1 || t[i] == t[j]) { nex[++ i] = ++ j; } else j = nex[j]; }}int main(){ scanf("%d%d%s",&n,&k,s); getnex(s,n); for(int i = 1;i <= n;i ++) { int d = i / (i - nex[i]); ans[i - 1] = '0' + ((i % (i - nex[i])) ? d / k > d % k : d / k >= d % k);///快速输出。循环输出太慢了。数据量太大。 } ans[n] = 0; printf("%s",ans);}