题意:给你一个字符串 ,问你前对于任意一个前缀能不能组成 A+B+A+B。。。+B+A 这种形式。
解题思路:在next数组上面乱搞,判断前缀是否循环 ,循环是否为K还是K+1,为K的时候往后DP看最多能符合条件的前缀串。
解题代码:
1 // File Name: d.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月06日 星期一 15时36分38秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 #define maxn 1000005 26 using namespace std; 27 int n , k ; 28 char str[1000005]; 29 int next[maxn]; 30 int len ; 31 void getnext(char *p ) 32 { 33 len = strlen(p); 34 next[0] = -1; 35 int k = -1; 36 int j = 0 ; 37 while(j < len) 38 { 39 if(k == -1 || p[j] == p[k]) 40 { 41 ++ k ; 42 ++ j; 43 next[j] = k ; 44 }else{ 45 k = next[k]; 46 } 47 } 48 } 49 int fa[maxn]; 50 int dp[maxn]; 51 int main(){ 52 scanf("%d %d",&n,&k); 53 scanf("%s",str); 54 getnext(str); 55 if(k == 1) 56 { 57 for(int i = 1; i <= len ;i ++) 58 putchar('1'); 59 return 0 ; 60 } 61 printf(" "); 62 int tmp = 0; 63 for(int i = 1; i <= len ;i ++) 64 { 65 int ok = 0 ; 66 67 tmp --; 68 if(tmp > 0 && next[i] == next[i-1]+1) 69 { 70 ok = 1; 71 } 72 if(next[i] != next[i-1] + 1) 73 { 74 tmp = 0 ; 75 } 76 if(i % k == 0 && next[i] != 0 && i % (i - next[i]) ==0 && (i/(i-next[i]))%k == 0) 77 { 78 ok = 1; 79 tmp = i /k ; 80 }else if(i % (k+1) == 0 && next[i] != 0 && i % (i - next[i]) ==0 && (i/(i-next[i]))%(k+1) == 0) 81 { 82 ok = 1; 83 } 84 if(ok) 85 printf("1"); 86 else printf("0"); 87 } 88 printf(" "); 89 90 return 0; 91 }