Distinct Substrings (spoj694)(后缀数组)
Posted zhangbuang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Distinct Substrings (spoj694)(后缀数组)相关的知识,希望对你有一定的参考价值。
核心:每一个后缀的每一个前缀都是一个子串
相邻后缀的lcp的值是就是重复子串的个数
用所有的子串减去sigma(height)就行了
1 #include"bits/stdc++.h" 2 using namespace std; 3 #define clr(x) memset(x,0,sizeof(x)) 4 5 int T; 6 char a[2000]; 7 int n,m; 8 int x[2000],y[2000],c[2000]; 9 int sa[2000]; 10 int rk[2000]; 11 int ht[2000]; 12 13 inline void SA() 14 { 15 //cout<<"%^("<<endl; 16 17 // cout<<n<<" "<<m<<endl; 18 //cout<<a+1<<endl; 19 /* memset(c,0,sizeof c); 20 memset(x,0,sizeof x); 21 memset(y,0,sizeof y);*/ 22 clr(c); 23 clr(x); 24 clr(y); 25 26 27 for (int i=1;i<=n;i++) ++c[x[i] = a[i]-‘A‘]; 28 for (int i=1;i<=m;i++) c[i]+=c[i-1]; 29 for (int i=n;i;i--) sa[c[x[i]]--] = i; 30 31 for (int k=1;k<=n;k*=2) 32 { 33 34 int num = 0; 35 for (int i=n-k+1;i<=n;i++) y[++num] = i; 36 for (int i=1;i<=n;i++) if (sa[i]>k) y[++num] = sa[i]-k; 37 memset(c,0,sizeof c); 38 for (int i=1;i<=n;i++) ++c[x[y[i]]]; 39 for (int i=1;i<=m;i++) c[i]+=c[i-1]; 40 for (int i=n;i;i--) sa[c[x[y[i]]]--] = y[i],y[i]=0; 41 num=1; 42 swap(x,y); 43 x[sa[1]]=1; 44 45 for (int i=2;i<=n;i++) 46 { 47 x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?num:++num; 48 } 49 50 if (num==n) break; 51 m=num; 52 53 54 } 55 56 for (int i=1;i<=n;i++) rk[sa[i]] = i; 57 int k = 0; 58 59 for (int i=1;i<=n;i++) 60 { 61 if (rk[i]==1) continue; 62 if (k) k--; 63 int j =sa[rk[i]-1]; 64 65 66 while (a[i+k]==a[j+k]&&i+k<=n&&j+k<=n) k++; 67 68 ht[rk[i]] = k; 69 } 70 71 // 72 // for (int i=1;i<=n;i++ ) cout<<ht[i]<<" ";cout<<endl; 73 // / / for (int i=1;i<=n;i++) cout<<sa[i]<<" ";cout<<endl; 74 75 76 } 77 78 79 80 int main() 81 { 82 cin>>T; 83 while (T--) 84 { 85 86 m=233; 87 cin>>a+1; 88 n = strlen(a+1); 89 SA(); 90 91 int ans = n*(n+1)/2; 92 for (int i=1;i<=n;i++ ) ans -= ht[i]; 93 cout<<ans<<endl; 94 95 96 97 }
以上是关于Distinct Substrings (spoj694)(后缀数组)的主要内容,如果未能解决你的问题,请参考以下文章
关于在eclipse for javaee中修改servlet新建模板