Power Strings POJ - 2406
Power Strings
kmp可以过的
学了sa就用sa搞一下,,一直TLE...
好像要用另外一种方法实现,还没学=_=
先放上超时的代码吧
1 //#include <bits/stdc++.h> 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 const int maxn = 1000010; 8 char s[maxn]; 9 int sa[maxn], t1[maxn], t2[maxn], c[maxn]; 10 int h[maxn], rk[maxn]; 11 int n; 12 void build_sa(int n, int m){ 13 int i, *x = t1, *y = t2; 14 for(i = 0; i < m; i++) c[i] = 0; 15 for(i = 0; i < n; i++) c[x[i] = s[i]]++; 16 for(i = 1; i < m; i++) c[i] += c[i-1]; 17 for(i = n-1; i >= 0; i--) sa[--c[x[i]]] = i; 18 for(int k = 1; k <= n; k <<= 1){ 19 int p = 0; 20 for(i = n-k; i < n; i++) y[p++] = i; 21 for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i]-k; 22 for(i = 0; i < m; i++) c[i] = 0; 23 for(i = 0; i < n; i++) c[x[y[i]]]++; 24 for(i = 1; i< m; i++) c[i] += c[i-1]; 25 for(i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i]; 26 swap(x,y); 27 p = 1; 28 x[sa[0]] = 0; 29 for(i = 1; i < n; i++) 30 x[sa[i]] = y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k]? p-1 : p++; 31 if(p>=n) break; 32 m=p; 33 } 34 } 35 void geth(int n){ 36 int i, j, k=0; 37 for(i = 0; i < n; i++) rk[sa[i]]=i; 38 for(i = 0; i < n; i++) { 39 if(k) k--; 40 j = sa[rk[i]-1]; 41 while(s[i+k]==s[j+k]) k++; 42 h[rk[i]] = k; 43 } 44 } 45 int main(){ 46 while(scanf("%s", s)){ 47 if(s[0] == '.') break; 48 int n = strlen(s) + 1; //!!! 49 build_sa(n, 255); 50 geth(n); 51 int k; 52 n--; 53 for(k = 1; k <= n; k++){ 54 if(n%k==0 && h[rk[0]] == n-k) break; 55 } 56 printf("%d\n", n/k); 57 } 58 }
DC3
找了个模板,,过了,日后有空再细看~
1 //#include <bits/stdc++.h> 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 /* 8 * 后缀数组 9 * DC3算法,复杂度O(n) 10 * 所有的相关数组都要开三倍 11 */ 12 const int MAXN = 1000010; 13 #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) 14 #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x)-tb) * 3 + 2) 15 16 int wa[MAXN * 3], wb[MAXN * 3], wv[MAXN * 3], wss[MAXN * 3]; 17 18 int c0(int *r, int a, int b) 19 { 20 return r[a] == r[b] && r[a + 1] == r[b + 1] && r[a + 2] == r[b + 2]; 21 } 22 23 int c12(int k, int *r, int a, int b) 24 { 25 if(k == 2) 26 { 27 return r[a] < r[b] || (r[a] == r[b] && c12(1, r, a + 1, b + 1)); 28 } 29 else 30 { 31 return r[a] < r[b] || (r[a] == r[b] && wv[a + 1] < wv[b + 1]); 32 } 33 } 34 35 void sort(int *r, int *a, int *b, int n, int m) 36 { 37 int i; 38 for (i = 0; i < n; i++) 39 { 40 wv[i] = r[a[i]]; 41 } 42 for (i = 0; i < m; i++) 43 { 44 wss[i] = 0; 45 } 46 for (i = 0; i < n; i++) 47 { 48 wss[wv[i]]++; 49 } 50 for (i = 1; i < m; i++) 51 { 52 wss[i] += wss[i - 1]; 53 } 54 for (i = n - 1; i >= 0; i--) 55 { 56 b[--wss[wv[i]]] = a[i]; 57 } 58 } 59 60 void dc3(int *r, int *sa, int n, int m) 61 { 62 int i, j, *rn = r + n; 63 int *san = sa + n, ta = 0, tb = (n+1)/3, tbc = 0, p; 64 r[n] = r[n+1] = 0; 65 for (i = 0; i < n; i++) 66 { 67 if (i % 3 != 0) 68 { 69 wa[tbc++] = i; 70 } 71 } 72 sort(r + 2, wa, wb, tbc, m); 73 sort(r + 1, wb, wa, tbc, m); 74 sort(r, wa, wb, tbc, m); 75 for (p = 1, rn[F(wb[0])] = 0, i = 1; i < tbc; i++) 76 { 77 rn[F(wb[i])] = c0(r, wb[i - 1], wb[i]) ? p - 1 : p++; 78 } 79 if (p < tbc) 80 { 81 dc3(rn, san, tbc, p); 82 } 83 else 84 { 85 for (i = 0; i < tbc; i++) 86 { 87 san[rn[i]] = i; 88 } 89 } 90 for (i = 0; i < tbc; i++) 91 { 92 if (san[i] < tb) 93 { 94 wb[ta++] = san[i] * 3; 95 } 96 } 97 if (n % 3 == 1) 98 { 99 wb[ta++] = n - 1; 100 } 101 sort(r, wb, wa, ta, m); 102 for (i = 0; i < tbc; i++) 103 { 104 wv[wb[i] = G(san[i])] = i; 105 } 106 for (i = 0, j = 0, p = 0; i < ta && j < tbc; p++) 107 { 108 sa[p] = c12(wb[j] % 3, r, wa[i], wb[j]) ? wa[i++] : wb[j++]; 109 } 110 for (; i < ta; p++) 111 { 112 sa[p] = wa[i++]; 113 } 114 for (; j < tbc; p++) 115 { 116 sa[p] = wb[j++]; 117 } 118 } 119 120 // str和sa也要三倍 121 void da(int str[], int sa[], int rk[], int h[], int n, int m) 122 { 123 for (int i = n; i < n * 3; i++) 124 { 125 str[i] = 0; 126 } 127 dc3(str, sa, n+1, m); 128 int i, j, k = 0; 129 for (i = 0; i <= n; i++) 130 { 131 rk[sa[i]] = i; 132 } 133 for (i = 0; i < n; i++) 134 { 135 if(k) 136 { 137 k--; 138 } 139 j = sa[rk[i] - 1]; 140 while (str[i + k] == str[j + k]) 141 { 142 k++; 143 } 144 h[rk[i]] = k; 145 } 146 } 147 //sa[i] :排名第 i 的后缀在哪(i 从 1 开始) 148 //rk[i]:后缀 i 排第几 (i 从 0 开始) 149 //h[i]:排名为 i 和 i-1 的两个后缀的最长公共前缀(LCP)长度 (i 从 2 开始) 150 int s[MAXN * 3]; 151 char str[MAXN * 3]; 152 int sa[MAXN * 3]; 153 int h[MAXN * 3],rk[MAXN * 3]; 154 155 int main(){ 156 //freopen("in.txt", "r", stdin); 157 while(scanf("%s", str)){ 158 if(str[0] == '.') break; 159 int n = strlen(str); 160 for(int i = 0; i < n; i++) s[i] = str[i] - 'a' + 1; 161 da(s, sa, rk, h, n, 300); 162 int k; 163 for(k = 1; k <= n; k++){ 164 if(n%k==0 && rk[0] == rk[k]+1 && h[rk[0]] == n-k) break; 165 } 166 if(k == n+1) k--; 167 printf("%d\n", n/k); 168 } 169 }
高级数据结构p399习题1