poj 2406 kmp求连续重复子串的个数
2014-10-15 20:26
344 查看
Power Strings
Description
Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the
empty string) and a^(n+1) = a*(a^n).
Input
Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.
Output
For each s you should print the largest n such that s = a^n for some string a.
Sample Input
Sample Output
Hint
This problem has huge input, use scanf instead of cin to avoid time limit exceed.
Source
Waterloo local 2002.07.01
用后缀数组写的超时啦。
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 33119 | Accepted: 13775 |
Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the
empty string) and a^(n+1) = a*(a^n).
Input
Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.
Output
For each s you should print the largest n such that s = a^n for some string a.
Sample Input
abcd aaaa ababab .
Sample Output
1 4 3
Hint
This problem has huge input, use scanf instead of cin to avoid time limit exceed.
Source
Waterloo local 2002.07.01
#include<stdio.h> #include<string.h> #define N 1000005 char str ; int next ; void getnext(char *str) { int i,n,j; n=strlen(str); next[0]=-1; j=-1; i=0; while(i<n) { if(j==-1||str[i]==str[j]) { i++; j++; next[i]=j; } else j=next[j]; } } int main() { int n; while(scanf("%s",str)!=EOF) { if(strcmp(str,".")==0) break; n=strlen(str); getnext(str); if(n%(n-next )==0) printf("%d\n",n/(n-next )); else printf("1\n"); } return 0; }
用后缀数组写的超时啦。
/*做法比较简单,穷举字符串 S 的长度 k,然后判断是否满足。判断的时候, 先看字符串 L 的长度能否被 k 整除,再看 suffix(1)和 suffix(k+1)的最长公共 前缀是否等于 n-k。在询问最长公共前缀的时候,suffix(1)是固定的,所以 RMQ 问题没有必要做所有的预处理,只需求出 height 数组中的每一个数到 height[rank[1]]之间的最小值即可。整个做法的时间复杂度为 O(n)。*/ #include<stdio.h> #include<iostream> #include<string.h> using namespace std; #define N 1000005 int t1 ,t2 ,x ,c ,sa ,s ,rank ,height ,b ; char str ; void build_sa(int *s,int n,int m) { int *x=t1,*y=t2,i,k; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[i]=s[i]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for(k=1;k<=n;k<<=1) { int p=0; for(i=n-k;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[y[i]]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1; x[sa[0]]=0; for(i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; if(p>=n) break; m=p; } } void getheight(int n) { int i,k=0,j; for(i=0;i<=n;i++) rank[sa[i]]=i; for(i=0;i<n;i++) { if(k) k--; j=sa[rank[i]-1]; while(s[j+k]==s[i+k]) k++; height[rank[i]]=k; } } int main() { int n,m,mi,i,k; while(scanf("%s",str)!=EOF) { n=strlen(str); for(i=0;str[i]!='\0';i++) s[i]=str[i]; s =0; build_sa(s,n+1,200); getheight(n); //for(i=1;i<=n;i++) // printf("high=%d\n",height[i]); m=rank[0]; mi=height[m]; // printf("m=%d mi=%d\n",m,mi); for(i=m;i>1;i--) { //printf("%d %d\n",i,height[i]); if(height[i]<mi) mi=height[i]; // printf("mi=%d\n",mi); b[i-1]=mi; } mi=height[m+1]; for(i=m+1;i<=n;i++) { if(height[i]<mi) mi=height[i]; b[i]=mi; } for(k=1;k<=n;k++) { m=rank[k]; if(b[m]==n-k) break; } printf("%d\n",n/k); } return 0; }
相关文章推荐
- poj 2406 连续重复子串(后缀数组DC3/kmp)
- poj(2406)求最短重复子串-KMP
- 【POJ 2406】Power Strings 连续重复子串
- POJ 2406 Power Strings(KMP求一个串的重复子串)
- poj 2406 求连续重复子串出现的次数 后缀数组
- POJ 2406 连续重复字符串(KMP)和后缀数组
- POJ-2406 Power Strings(KMP求重复子串出现的最大次数)
- POJ 2406(连续重复子串)
- POJ - 2406 Power Strings解题报告(KMP,字符串划分成若干连续相同子串)
- POJ 2406 Power Strings(后缀数组[连续重复子串])
- poj 2406 Power Strings(连续重复子串)
- POJ 2406 后缀数组:求连续重复子串
- poj_2406 KMP寻找重复子串问题
- POJ 2406 Power Strings 求连续重复字串(kmp)
- poj 2406 KMP 重复子串
- POJ 2406-Power Strings(重复子串-KMP中的next数组)
- poj 2406 Power Strings(kmp求一个串的重复子串)
- POJ 3693 Maximum repetition substring (求重复次数最多的连续子串,4级)
- poj 2406 求字符串中重复子串的个数
- poj 1961 Period (最小重复子串 kmp)