Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 36063 | Accepted: 14902 |
Description
Input
Output
Sample Input
abcd aaaa ababab .
Sample Output
1 4 3
第一道kmp:
mp算法:(172ms)
#include <cstdio> #include <cstring> #define MAX 1000000+10 using namespace std; char P[MAX]; int f[MAX]; void getfail() { int i, j; int len = strlen(P); f[0] = f[1] = 0; for(i = 1; i < len; i++) { j = f[i]; while(j && P[i] != P[j]) j = f[j]; f[i+1] = P[i]==P[j]?j+1:0; } } int main() { int len; while(scanf("%s", P), P[0] != '.') { getfail(); len = strlen(P); if(len % (len-f[len])) printf("1\n"); else printf("%d\n", len/(len-f[len])); } return 0; }
kmp算法:(110ms)
#include <cstdio> #include <cstring> #include <cmath> #define MAX 1000000+10 using namespace std; char P[MAX], T[MAX]; int f[MAX]; void getfail()//优化失配函数 { int i = 0, j = -1; f[0] = -1; int len = strlen(P); while(i < len) { if(j == -1 || P[i] == P[j]) f[++i] = ++j; else j = f[j]; } } int main() { int len; while(scanf("%s", P), P[0] != '.') { getfail(); len = strlen(P); if(len % (len-f[len])) printf("1\n"); else printf("%d\n", len/(len-f[len])); } return 0; }
后缀数组:思路:我们枚举连续子串的末尾,得到一个长度k,然后判断当前的k是否可行。方法是LCP(suffix(i), suffix(i+k)) == n - k。直接RMQ会MLE,我们用dp去维护这个直接可以了,因为一个点是固定的。倍增会T,用dc3。。。。
AC代码:
//#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #include <stack> #define PI acos(-1.0) #define CLR(a, b) memset(a, (b), sizeof(a)) #define fi first #define se second #define ll o<<1 #define rr o<<1|1 using namespace std; typedef long long LL; typedef pair<int, int> pii; const int MAXN = 1e6 + 10; const int pN = 1e6;// <= 10^7 const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; void add(LL &x, LL y) { x += y; x %= MOD; } #define F(x) ((x)/3+((x)%3==1?0:tb)) #define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2) int wa[MAXN], wb[MAXN], wv[MAXN], ws[MAXN]; int c0(int *r, int a, int b) { return r[a] == r[b] && r[a+1] == r[b+1] && r[a+2] == r[b+2]; } int c12(int k, int *r, int a, int b) { if(k == 2) return r[a] < r[b] || r[a] == r[b] && c12(1, r, a+1, b+1); else return r[a] < r[b] || r[a] == r[b] && wv[a+1] < wv[b+1]; } void Sort(int *r, int *a, int *b, int n, int m) { int i; for(i = 0; i < n; i++) wv[i] = r[a[i]]; for(i = 0; i < m; i++) ws[i] = 0; for(i = 0; i < n; i++) ws[wv[i]]++; for(i = 1; i < m; i++) ws[i] += ws[i-1]; for(i= n-1; i >= 0; i--) b[--ws[wv[i]]] = a[i]; } void dc3(int *r, int *sa, int n, int m) { int i, j, *rn = r+n, *san = sa+n, ta = 0, tb = (n+1)/3, tbc = 0, p; r[n] = r[n+1] = 0; for(i = 0; i < n; i++) if(i % 3) wa[tbc++] = i; Sort(r+2, wa, wb, tbc, m); Sort(r+1, wb, wa, tbc, m); Sort(r, wa, wb, tbc, m); for(p = 1, rn[F(wb[0])] = 0, i = 1; i < tbc; i++) rn[F(wb[i])] = c0(r,wb[i-1],wb[i]) ? p-1 : p++; if(p < tbc) dc3(rn, san, tbc, p); else for(i = 0; i < tbc; i++) san[rn[i]] = i; for(i = 0; i < tbc; i++) if(san[i] < tb) wb[ta++] = san[i]*3; if(n % 3 == 1) wb[ta++] = n-1; Sort(r, wb, wa, ta, m); for(i = 0; i < tbc; i++) wv[wb[i] = G(san[i])] = i; for(i = 0, j = 0, p = 0; i < ta && j < tbc; p++) sa[p] = c12(wb[j]%3, r, wa[i], wb[j]) ? wa[i++] : wb[j++]; for(; i < ta; p++) sa[p] = wa[i++]; for(; j < tbc; p++) sa[p] = wb[j++]; } int R[MAXN*3], H[MAXN*3]; void calh(int *r, int *sa, int n) { int i, j, k = 0; for(i = 1; i <= n; i++) R[sa[i]] = i; for(i = 0; i < n; H[R[i++]] = k) for(k ? k-- : 0, j = sa[R[i]-1]; r[i+k] == r[j+k]; k++); } int sa[MAXN*3]; int a[MAXN]; char str[MAXN]; int dp[MAXN]; void dp_init(int n) { CLR(dp, INF); int id = R[0]; for(int i = id-1; i >= 1; i--) { if(i == id-1) dp[i] = H[i+1]; else dp[i] = min(dp[i+1], H[i+1]); } for(int i = id+1; i <= n; i++) { if(i == id + 1) dp[i] = H[i]; else dp[i] = min(dp[i-1], H[i]); } } int main() { while(scanf("%s", str), str[0] != '.') { int n = strlen(str); int Max = 0; if(n & 1) { printf("1\n"); continue; } for(int i = 0; i < n; i++) { a[i] = str[i] - 'a' + 1; Max = max(Max, a[i]); } a[n] = 0; dc3(a, sa, n+1, Max+1);//<n+1 calh(a, sa, n);//<=n dp_init(n); int ans = 1; for(int i = 1; i <= n/2; i++) { if(n % i == 0) { if(dp[R[i]] == n - i) { ans = n / i; break; } } } printf("%d\n", ans); } return 0; }