BZOJ 1031 后缀数组

题解:

把原串直接接在后头,然后后缀数组本来就排序好了,正好用来求题目所需~

 

毛线的,nlogn的就是烦,还是nlog^2n的好写,,

View Code
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <cstdio>
 6 
 7 #define N 220000
 8 
 9 using namespace std;
10 
11 char s[N];
12 int rank[N],sa[N];
13 int wa[N],wb[N],wc[N],wv[N];
14 int p[N];
15 
16 inline bool cmp(int *r,int a,int b,int l)
17 {
18     return r[a]==r[b]&&r[a+l]==r[b+l];
19 }
20 
21 inline void da(char *r,int *sa,int n,int m)
22 {
23     int i,j,p,*x=wa,*y=wb,*t;
24     for(i=0;i<m;i++) wc[i]=0;
25     for(i=0;i<n;i++) wc[x[i]=r[i]]++;
26     for(i=1;i<m;i++) wc[i]+=wc[i-1];
27     for(i=n-1;i>=0;i--) sa[--wc[x[i]]]=i;
28     for(j=1,p=1;p<n;j<<=1,m=p)
29     {
30         for(i=n-j,p=0;i<n;i++) y[p++]=i;
31         for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
32         for(i=0;i<n;i++) wv[i]=x[y[i]];
33         for(i=0;i<m;i++) wc[i]=0;
34         for(i=0;i<n;i++) wc[wv[i]]++;
35         for(i=1;i<m;i++) wc[i]+=wc[i-1];
36         for(i=n-1;i>=0;i--) sa[--wc[wv[i]]]=y[i];
37         for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
38             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
39     }
40 }
41 
42 inline void go()
43 {
44     scanf("%s",s);
45     int slen=strlen(s);
46     int n=slen*2;
47     for(int i=0;i<slen;i++) s[slen+i]=s[i];
48     s[n-1]=0;
49     da(s,sa,n,300);
50     for(int i=0;i<n;i++) rank[sa[i]]=i;
51     for(int i=0;i<slen;i++) p[rank[i]]=s[i+slen-1];
52     for(int i=0;i<n;i++)
53         if(p[i]) printf("%c",p[i]);
54 }
55 
56 int main()
57 {
58     go();
59     return 0;
60 }

 

 

posted @ 2013-03-05 21:18  proverbs  阅读(949)  评论(0编辑  收藏  举报