Qiuqiqiu  
不管道路多么崎岖坎坷,我永远不停下追逐梦想的脚步!

http://acm.hdu.edu.cn/showproblem.php?pid=3518

后缀数组

View Code
 1 //3518
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 int Max(int x,int y) {return x>y?x:y;}
 7 int Min(int x,int y) {return x<y?x:y;}
 8 const int L=1010;
 9 char str[L];
10 int r[L],wa[L],wb[L],ws[L];
11 int sa[L],rank[L],high[L];
12 bool cmp(int *r,int a,int b,int l)
13 {
14     return (r[a]==r[b]&&r[a+l]==r[b+l]);
15 }
16 void suffix(int *r,int n,int m)
17 {
18     int *x=wa,*y=wb;
19     for(int i=0;i<m;i++) ws[i]=0;
20     for(int i=0;i<n;i++) ws[x[i]=r[i]]++;
21     for(int i=1;i<m;i++) ws[i]+=ws[i-1];
22     for(int i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;
23     for(int j=1,p=1;p<n;j<<=1,m=p)
24     {
25         p=0;
26         for(int i=n-j;i<n;i++) y[p++]=i;
27         for(int i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
28         for(int i=0;i<m;i++) ws[i]=0;
29         for(int i=0;i<n;i++) ws[x[y[i]]]++;
30         for(int i=1;i<m;i++) ws[i]+=ws[i-1];
31         for(int i=n-1;i>=0;i--) sa[--ws[x[y[i]]]]=y[i];
32         int *t=x; x=y; y=t;
33         p=1;
34         x[sa[0]]=0;
35         for(int i=1;i<n;i++)
36             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
37     }
38     for(int i=1;i<n;i++) rank[sa[i]]=i;
39     for(int i=0,k=0;i<n-1;i++)
40     {
41         if(k) k--;
42         int j=sa[rank[i]-1];
43         while(r[i+k]==r[j+k]) k++;
44         high[rank[i]]=k;
45     }
46 }
47 int get(int l,int n)
48 {
49     int cnt=0,max=sa[1],min=sa[1];
50     for(int i=2;i<n;i++)
51         if(high[i]>=l)
52         {
53             max=Max(max,sa[i]);
54             min=Min(min,sa[i]);
55         }
56         else
57         {
58             if(max-min>=l) cnt++;
59             max=min=sa[i];
60         }
61     if(max-min>=l) cnt++;
62     return cnt;
63 }
64 int main()
65 {
66     while(scanf("%s",str),strcmp(str,"#"))
67     {
68         int len=strlen(str);
69         for(int i=0;str[i];i++) r[i]=str[i]-'a'+1;
70         r[len++]=0;
71         suffix(r,len,27);
72         int ans=0;
73         for(int i=1;i<=(len-1)/2;i++) ans+=get(i,len);
74         printf("%d\n",ans);
75     }
76     return 0;
77 }

 

posted on 2012-05-04 09:30  Qiuqiqiu  阅读(290)  评论(0编辑  收藏  举报