标签:others ash 位置 test repr exce bool log 不同的
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3182 Accepted Submission(s): 1319
字符串 后缀数组
求至少不重叠出现2次以上的子串有多少个
建立后缀数组,按height把后缀们分成不同的组,同一组内都是相同的后缀,统计它们出现的最大最小位置即可
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 const int mxn=100010; 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 13 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 14 return x*f; 15 } 16 int sa[mxn],rk[mxn],ht[mxn]; 17 int wa[mxn],wb[mxn],wv[mxn],cnt[mxn]; 18 char s[mxn]; 19 inline int cmp(int *r,int a,int b,int l){ 20 return r[a]==r[b] && r[a+l]==r[b+l]; 21 } 22 void GSA(int *sa,int n,int m){ 23 int i,j,k; 24 int *x=wa,*y=wb; 25 for(i=0;i<m;i++)cnt[i]=0; 26 for(i=0;i<n;i++)cnt[x[i]=s[i]-‘a‘+1]++; 27 for(i=1;i<m;i++)cnt[i]+=cnt[i-1]; 28 for(i=n-1;i>=0;i--)sa[--cnt[x[i]]]=i; 29 for(int p=0,j=1;p<n;j<<=1,m=p){ 30 for(p=0,i=n-j;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++) 33 wv[i]=x[y[i]]; 34 for(i=0;i<m;i++)cnt[i]=0; 35 for(i=0;i<n;i++)cnt[wv[i]]++; 36 for(i=1;i<m;i++)cnt[i]+=cnt[i-1]; 37 for(i=n-1;i>=0;i--)sa[--cnt[wv[i]]]=y[i]; 38 swap(x,y); 39 p=1;x[sa[0]]=0; 40 for(i=1;i<n;i++) 41 x[sa[i]]=cmp(y,sa[i],sa[i-1],j)?p-1:p++; 42 } 43 return; 44 } 45 void GHT(int n){ 46 int i,j,k=0; 47 for(i=1;i<=n;i++)rk[sa[i]]=i; 48 for(i=0;i<n;i++){ 49 if(k)k--; 50 j=sa[rk[i]-1]; 51 while(s[i+k]==s[j+k])k++; 52 ht[rk[i]]=k; 53 } 54 return; 55 } 56 int ans=0; 57 bool solve(int n,int lim){ 58 bool flag=0; 59 int mxpos=-100,mnpos=mxn; 60 for(int i=1;i<=n;i++){ 61 if(ht[i]<lim){ 62 if(mxpos-mnpos>=lim){ 63 ans++;flag=1; 64 } 65 mxpos=-100,mnpos=mxn; 66 } 67 mxpos=max(mxpos,sa[i]); 68 mnpos=min(mnpos,sa[i]); 69 } 70 if(mxpos-mnpos>=lim)flag=1,ans++; 71 return flag; 72 } 73 int main(){ 74 int i,j; 75 while(scanf("%s",s) && s[0]!=‘#‘){ 76 int len=strlen(s); 77 s[len]=‘a‘-1; 78 GSA(sa,len+1,28); 79 GHT(len); 80 ans=0; 81 // for(i=0;i<=len;i++)printf("%c",s[i]);puts(""); 82 // for(i=1;i<=len;i++)printf("%d ",sa[i]);puts(""); 83 // for(i=1;i<=len;i++)printf("%d ",ht[i]);puts(""); 84 for(i=1;i<len;i++){ 85 if(!solve(len,i))break; 86 } 87 printf("%d\n",ans); 88 } 89 return 0; 90 }
标签:others ash 位置 test repr exce bool log 不同的
原文地址:http://www.cnblogs.com/SilverNebula/p/6648740.html