1. 程式人生 > >[HDU]3518——Boring counting

[HDU]3518——Boring counting

break ble tin col figure take in fine each face

zhan.jiang.ou now faced a tough problem,his english teacher quan.hong.chun gives him a string,which consists with n lower case letter,he must figure out how many substrings appear at least twice,moreover,such apearances can not overlap each other.
Take aaaa as an example.”a” apears four times,”aa” apears two times without overlaping.however,aaa can’t apear more than one time without overlaping.since we can get “aaa” from [0-2](The position of string begins with 0) and [1-3]. But the interval [0-2] and [1-3] overlaps each other.So “aaa” can not take into account.Therefore,the answer is 2(“a”,and “aa”).

題目大意:求一個字符串的不重疊子串的個數。

思路:我真是太辣雞了,其實這個題就是後綴數組性質②的應用,只不過是求出每個長度的答案(性質詳見我的後綴數組的基本使用技巧)!

總結:後綴數組英語應用太靈活,多回顧反思!

 1 #include<map>
 2 #include<set>
 3 #include<list>
 4 #include<deque>
 5 #include<cmath>
 6 #include<queue>
 7 #include<stack>
 8 #include<vector>
 9
#include<cstdio> 10 #include<complex> 11 #include<cstring> 12 #include<cstdlib> 13 #include<iostream> 14 #include<algorithm> 15 #define LL long long 16 #define db double 17 #define RG register 18 #define maxx 1001 19 #define Inf 666666 20 using namespace std;int tong[maxx];
21 int sa[maxx],X[maxx],Y[maxx],rnk[maxx],height[maxx],num[maxx];char s[maxx]; 22 bool comp(int *r,int a,int b,int len){ 23 return r[a]==r[b]&&r[a+len]==r[b+len]; 24 } 25 void build_sa(int len){ 26 int *x=X,*y=Y,*t,Max=maxx/2; 27 memset(tong,0,sizeof(tong)); 28 for(int i=0;i<len;++i) 29 tong[x[i]=num[i]]++; 30 for(int i=1;i<=Max;++i) 31 tong[i]+=tong[i-1]; 32 for(int i=len-1;i!=-1;i--) 33 sa[--tong[x[i]]]=i; 34 for(int j=1,p=1,i;p<len;j<<=1,Max=p){ 35 for(i=len-1,p=0;i>=len-j;--i)y[p++]=i; 36 for(i=0;i<len;++i) 37 if(sa[i]>=j)y[p++]=sa[i]-j; 38 for(i=0;i<=Max;++i) 39 tong[i]=0; 40 for(i=0;i<len;++i) 41 tong[x[y[i]]]++; 42 for(i=1;i<Max;++i) 43 tong[i]+=tong[i-1]; 44 for(i=len-1;i!=-1;i--) 45 sa[--tong[x[y[i]]]]=y[i]; 46 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<len;++i) 47 x[sa[i]]=comp(y,sa[i],sa[i-1],j)?p-1:p++; 48 } 49 }int n; 50 void geth(){ 51 int j,k=0; 52 for(int i=1;i<=n;++i) 53 rnk[sa[i]]=i; 54 for(int i=0;i<n;height[rnk[i++]]=k) 55 for(k?k--:0,j=sa[rnk[i]-1];num[i+k]==num[j+k];k++); 56 } 57 void ans(){LL ans=0; 58 for(RG int len=1;len<=(n/2);++len){ 59 int Max=-Inf,Min=Inf; 60 for(RG int i=1;i<=n;++i){ 61 if(height[i]<len){ 62 if(Max-Min>=len)ans++; 63 Max=-Inf,Min=Inf; 64 } 65 Max=max(Max,sa[i]); 66 Min=min(Min,sa[i]); 67 if(i==n&&Max-Min>=len)ans++; 68 } 69 } 70 printf("%lld\n",ans); 71 } 72 int main(){ 73 while(scanf("%s",s)){ 74 n=strlen(s); 75 if(n==1&&s[0]==#)break; 76 memset(rnk,0,sizeof(rnk)); 77 memset(height,0,sizeof(height)); 78 memset(sa,0,sizeof(sa)); 79 memset(X,0,sizeof(X)); 80 memset(Y,0,sizeof(Y)); 81 for(int i=0;i<n;++i) 82 num[i]=s[i]-55; 83 num[n]=0; 84 build_sa(n+1); 85 geth(); 86 ans(); 87 } 88 return 0; 89 }

[HDU]3518——Boring counting