poj2774:对后缀数组的复仇,O(nlog n)做法

话说上次发了一篇文章..A掉了2774这道水题,但是!用的是O(nlog^2 n)做法,有些不服..

于是本人又研究了一次后缀数组的O(nlog n)做法,终于在昨晚领悟了!特A一题..终于可以教会师弟师妹们这一种数据结构了..哭

直接上代码吧..

 1 /*
 2 Source Code
 3 
 4 Problem: 2774       User: aclolicon
 5 Memory: 5212K       Time: 610MS
 6 Language: G++       Result: Accepted
 7 Source Code*/
 8 #include<cstdio>
 9 #include<iostream>
10 #include<cstring>
11 #define MAXN 200500
12 using namespace std;
13 char s[MAXN], s2[MAXN];
14 int n, len;
15 int sa[MAXN], c[MAXN], t[MAXN], t2[MAXN], rank[MAXN], height[MAXN];
16 void buildsa(){
17     int *x = t, *y = t2, m = 300;
18     memset(c, 0, sizeof(c));
19  
20     for (int i = 0; i < n; i++) c[x[i] = s[i]]++;
21     for (int i = 1; i < m; i++) c[i] += c[i - 1];
22     for (int i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
23     for (int k = 1; k <= n; k *= 2){
24         int p = 0;
25         for (int i = n - k; i < n; i++) y[p++] = i;
26         for (int i = 0; i < n; i++) if (sa[i] >= k) y[p++] = sa[i] - k;
27         memset(c, 0, sizeof(c));
28         for (int i = 0; i < n; i++) c[x[y[i]]]++;
29         for (int i = 1; i < m; i++) c[i] += c[i - 1];
30         for (int i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] =y[i];
31         swap(x, y);
32         p = 1;
33         x[sa[0]] = 0;
34         for (int 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++;
35         if (p >= n) break;
36         m = p;
37     }    
38 }
39  
40 void geth(){
41     n = strlen(s);
42     for (int i = 0; i <= n; i++) rank[sa[i]] = i;
43     int h = 0;
44     height[0] = 0;
45     for (int i = 0; i < n; i++){
46         int j = sa[rank[i] - 1];
47         if (h > 0) h--;
48         for (; j + h < n && i + h < n; h++){
49             if (s[j + h] != s[i + h]) break;
50         }
51         height[rank[i] - 1] = h;
52     }
53 }
54 int main(){
55     while(scanf("%s", s) > 0){
56         scanf("%s", s2) > 0;
57         len = strlen(s2);
58         n = strlen(s); 
59         if (s2 > s) swap(s, s2);
60         s[len] = '$';
61         for (int i = len + 1; i < len + n + 1; i++) s[i] = s2[i - len - 1];
62         n = strlen(s) + 1; 
63         buildsa();
64         geth();
65         int maxh = -1;
66         for (int i = 0; i < n; i++){
67             if((sa[i] < len) != (sa[i + 1] < len)){
68                 maxh = max(maxh, height[i]);
69             }
70         }
71         printf("%d", maxh);
72     }
73 }

 

posted @ 2016-05-27 22:03  b分之a  阅读(188)  评论(0编辑  收藏  举报