hdu_3518_Boring counting(后缀数组)

题目链接:hdu_3518_Boring counting

题意:

给你一个字符串,让你找不重叠且出现大于1次以上的字串个数

题解:

后缀数组height数组的应用,我们枚举字串的长度,然后将height数组分段,符合条件就ans++

为什么要这样做,因为height数组存的是相邻排名后缀的最大前缀数,如果height的值大于等于我们枚举的长度len,

那么有可能这一段存在有两个以上的该长度的字串,然后我们统计这个段的开头长度l和结束长度r,如果r-l>=len,说明这段必有

大于一个以上的该长度的相同子串,因为我们每次都是枚举len,按len分的段,所以不会重复。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;++i)
 3 using namespace std;
 4 
 5 namespace suffixarray{
 6     #define FN(n) for(int i=0;i<n;i++)
 7     const int N =1E3+7;
 8     int rnk[N],sa[N],height[N],c[N];char s[N];
 9     void getsa(int n,int m,int *x=rnk,int *y=height){
10         FN(m)c[i]=0;FN(n)c[x[i]=s[i]]++;FN(m)c[i+1]+=c[i];
11         for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
12         for(int k=1,p;p=0,k<=n;k=p>=n?N:k<<1,m=p){
13             for(int i=n-k;i<n;i++)y[p++]=i;
14             FN(n)if(sa[i]>=k)y[p++]=sa[i]-k;
15             FN(m)c[i]=0;FN(n)c[x[y[i]]]++;FN(m)c[i+1]+=c[i];
16             for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
17             swap(x,y),p=1,x[sa[0]]=0;
18             for(int i=1;i<n;i++)
19             x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
20         }
21         FN(n)rnk[sa[i]]=i;
22         for(int i=0,j,k=0;i<n-1;height[rnk[i++]]=k)
23         for(k=k?k-1:k,j=sa[rnk[i]-1];s[i+k]==s[j+k];k++);
24     }
25 }
26 
27 inline void upd(int &a,int b){if(a>b)a=b;}
28 inline void upu(int &a,int b){if(a<b)a=b;}
29 
30 using namespace suffixarray;
31 int main(){
32     while(~scanf("%s",s))
33     {
34         if(s[0]=='#')break;
35         int len=strlen(s),ans=0;
36         getsa(len+1,128);
37         F(i,1,len)
38         {
39             int l=len+1,r=0;
40             F(j,1,len)
41             {
42                 if(height[j]>=i)upd(l,sa[j]),upu(r,sa[j]);
43                 else
44                 {
45                     if(r-l>=i)ans++;
46                     l=r=sa[j];
47                 }
48             }
49             if(r-l>=i)ans++;
50         }
51         printf("%d
",ans);
52     }
53     return 0;
54 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/5744647.html