[SPOJ705]DISUBSTR - Distinct Substrings(后缀数组)
2016-12-26 11:24
483 查看
题目描述
传送门题解
每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数。如果所有的后缀按照suffix(sa[1]), suffix(sa[2]),suffix(sa[3]), …… ,suffix(sa) 的顺序计算,不难发现,对于每一次新加进来的后缀suffix(sa[k]), 它将产生 n-sa[k]+1 个新的前缀。但是其中有 height[k] 个是和前面的字符串的前缀是相同的。所以 suffix(sa[k]) 将 贡献出 n-sa[k]+1-height[k] 个不同的子串。累加后便是原问题的答案。
代码
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define N 50005 int T,n,m,ans; char s ; int *x,*y,X ,Y ,c ,sa ,height ,rank ; void clear() { n=ans=0; memset(X,0,sizeof(X));memset(Y,0,sizeof(Y));memset(c,0,sizeof(c)); memset(sa,0,sizeof(sa));memset(height,0,sizeof(height));memset(rank,0,sizeof(rank)); } void build_sa() { m=200; x=X,y=Y; for (int i=0;i<m;++i) c[i]=0; for (int i=0;i<n;++i) ++c[x[i]=s[i]]; for (int i=0;i<m;++i) c[i]+=c[i-1]; for (int i=n-1;i>=0;--i) sa[--c[x[i]]]=i; for (int k=1;k<=n;k<<=1) { int p=0; for (int i=n-k;i<n;++i) y[p++]=i; for (int i=0;i<n;++i) if (sa[i]>=k) y[p++]=sa[i]-k; for (int i=0;i<m;++i) c[i]=0; for (int i=0;i<n;++i) ++c[x[y[i]]]; for (int i=0;i<m;++i) c[i]+=c[i-1]; for (int i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1;x[sa[0]]=0; for (int i=1;i<n;++i) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&((sa[i-1]+k<n?y[sa[i-1]+k]:-1)==(sa[i]+k<n?y[sa[i]+k]:-1))?p-1:p++; if (p>n) break; m=p; } } void build_height() { for (int i=0;i<n;++i) rank[sa[i]]=i; int k=0;height[0]=0; for (int i=0;i<n;++i) { if (!rank[i]) continue; if (k) --k; int j=sa[rank[i]-1]; while (i+k<n&&j+k<n&&s[i+k]==s[j+k]) ++k; height[rank[i]]=k; } } int main() { scanf("%d\n",&T); while (T--) { clear(); gets(s);n=strlen(s); build_sa(); build_height(); for (int i=0;i<n;++i) ans+=n-sa[i]-height[i]; printf("%d\n",ans); } }
相关文章推荐
- [SPOJ705]DISUBSTR(后缀数组)
- SPOJ694&&SPOJ705 DISUBSTR - Distinct Substrings && SUBST1 - New Distinct Substrings 后缀数组
- SPOJ DISUBSTR - Distinct Substrings(不同子串数量 后缀数组)
- SPOJ DISUBSTR Distinct Substrings(后缀数组)
- SPOJ DISUBSTR(后缀数组)
- Distinct Substrings SPOJ - DISUBSTR 后缀数组(计算不同的子串数目)
- SPOJ DISUBSTR ——后缀数组
- C - Distinct Substrings SPOJ - DISUBSTR (后缀数组)
- SPOJ DISUBSTR(后缀数组)
- [SPOJ DISUBSTR]Distinct Substrings(后缀数组)
- SPOJ DISUBSTR 后缀数组
- SPOJ - DISUBSTR (后缀数组)
- spoj 694 DISUBSTR - Distinct Substrings (后缀数组)
- SPOJ694--- DISUBSTR - Distinct Substrings(后缀数组)
- SPOJ705 SUBST1 - New Distinct Substrings(后缀数组)
- SPOJ 694 Distinct Substrings/SPOJ 705 New Distinct Substrings(后缀数组)
- SPOJ 705 New Distinct Substrings (后缀数组)
- SPOJ705-New Distinct Substrings-后缀数组
- SPOJ 705 New DistinctSubstrings (后缀数组)
- SPOJ DISUBSTR 后缀数组