SPOJ 694 Distinct Substrings <后缀数组>

来源:互联网 发布:显示器尺寸 知乎 编辑:程序博客网 时间:2024/06/10 18:34

题目:传送门


分析:

后缀数组水题。求有多少个不相同的子串,ans=n*(n+1)/2-sigma(height[1...n])。


代码:

#include <iostream>#include <algorithm>#include <string>using namespace std;const int MAXN=1005;int sa[MAXN],wm[MAXN],wa[MAXN],wb[MAXN],height[MAXN];int *rank;bool cmp(int* r,int a,int b,int len){return r[a]==r[b]&&r[a+len]==r[b+len];}void da(const string& data,int n,int m){int *x=wa,*y=wb,*t,i,j,p;for(i=0;i<m;++i) wm[i]=0;for(i=0;i<n;++i) ++wm[x[i]=data[i]];for(i=1;i<m;++i) wm[i]+=wm[i-1];for(i=n-1;i>=0;--i) sa[--wm[x[i]]]=i;for(j=1,p=1;p<n;j<<=1,m=p){for(p=0,i=n-j;i<n;++i) y[p++]=i;for(i=0;i<n;++i) if(sa[i]>=j) y[p++]=sa[i]-j;for(i=0;i<m;++i) wm[i]=0;for(i=0;i<n;++i) ++wm[x[y[i]]];for(i=1;i<m;++i) wm[i]+=wm[i-1];for(i=n-1;i>=0;--i) sa[--wm[x[y[i]]]]=y[i];for(t=x,x=y,y=t,i=p=1,x[sa[0]]=0;i<n;++i) x[sa[i]]=cmp(y,sa[i],sa[i-1],j)?p-1:p++;}rank=x; }int getHeight(const string& data,int n){int sum=0;for(int i=0,j,k=0;i<n;sum+=height[rank[i++]]=k)for(k?--k:k,j=sa[rank[i]-1];data[i+k]==data[j+k];++k);return sum;}int main(){ios::sync_with_stdio(false);int T; cin>>T;string str;while(T--){cin>>str;str.push_back(0);int n=str.size();da(str,n,130);cout<<(n-1)*n/2-getHeight(str,n-1)<<endl;}return 0;}


0 0
原创粉丝点击