Power Strings POJ - 2406

Power Strings

 POJ - 2406 

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 }
View Code

 

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 }
View Code

 

 



高级数据结构p399习题1

 

posted @ 2017-10-14 17:22  yijiull  阅读(143)  评论(0编辑  收藏  举报