【SPOJ705】New Distinct Substrings 后缀数组
2017-03-18 09:28
573 查看
题目描述
Given a string, we need to find the total number of its distinct substrings.题目大意
求一个字符串有多少个不同的子串。数据范围
长度小于200000,中间可能有空格。样例输入
ABABA样例输出
9解题思路
后缀数组,求出sa,rank,height。对于每一个新的后缀,则会产生它的长度个前缀,但其中是有重复的,需要减掉。height[i]=LCP(rank[i],rank[i-1]),所以答案就是∑i=1n(n−Sai−Heighti+1)
还有就是答案会爆int虽然这很显然
代码
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> using namespace std; inline int Getint(){int x=0,f=1;char ch=getchar();while('0'>ch||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;} namespace Suffix_Array{ #define Suffix_Maxn 200005 char s[Suffix_Maxn]; int a[Suffix_Maxn],sa[2][Suffix_Maxn],rk[2][Suffix_Maxn],height[Suffix_Maxn],v[Suffix_Maxn]; int Sa[Suffix_Maxn],Rank[Suffix_Maxn]; int k,n,p=0,q=1; void Mul(int *rk,int *sa,int *RK,int *SA){ for(int i=1;i<=n;i++)v[rk[sa[i]]]=i; for(int i=n;i>=1;i--)if(sa[i]>k)SA[v[rk[sa[i]-k]]--]=sa[i]-k; for(int i=n-k+1;i<=n;i++)SA[v[rk[i]]--]=i; for(int i=1;i<=n;i++)RK[SA[i]]=RK[SA[i-1]]+(rk[SA[i]]!=rk[SA[i-1]]||(rk[SA[i]+k]!=rk[SA[i-1]+k])); } void Suffix_Init(int m){ for(int i=1;i<=n;i++)v[a[i]]++; for(int i=1;i<=m;i++)v[i]+=v[i-1]; for(int i=n;i>=1;i--)sa[p][v[a[i]]--]=i; for(int i=1;i<=n;i++)rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i-1]]!=a[sa[p][i]]); for(k=1;k<n;k<<=1,swap(p,q))Mul(rk[p],sa[p],rk[q],sa[q]); memcpy(Sa,sa[p],sizeof(sa[p])); memcpy(Rank,rk[p],sizeof(rk[p])); for(int i=1,k=0;i<=n;i++){ int j=Sa[Rank[i]-1]; while(a[i+k]==a[j+k])k++; height[Rank[i]]=k; if(k>0)k--; } } } using namespace Suffix_Array; int main(){ gets(s); n=strlen(s); for(int i=1;i<=n;i++)a[i]=s[i-1]; Suffix_Init(666); unsigned long long Ans=0; for(int i=1;i<=n;i++) Ans+=n-Sa[i]-height[i]+1; cout<<Ans<<"\n"; return 0; }
相关文章推荐
- SPOJ 题目705 New Distinct Substrings(后缀数组,求不同的子串个数)
- SPOJ 题目705 New Distinct Substrings(后缀数组,求不同的子串个数)
- SPOJ 705 SUBST1 New Distinct Substrings 后缀数组
- SPOJ 705 New Distinct Substrings 后缀数组
- SPOJ SUBST1 New Distinct Substrings 后缀数组-子串个数
- SPOJ SUBST1 - New Distinct Substrings(后缀数组[不相同的子串的个数])
- 【SPOJ-SUBST1】New Distinct Substrings【后缀数组】
- [后缀数组、不重复子串]SPOJ694、spoj705--Distinct Substrings
- [后缀数组]spoj694 Distinct Substrings/spoj705 New Distinct Substrings
- SPOJ - Distinct Substrings / SPOJ - New Distinct Substrings(后缀数组 - 不相同子串个数)
- 【后缀数组 不同的字串个数】SPOJ - SUBST1 New Distinct Substrings
- SPOJ 705 New DistinctSubstrings (后缀数组)
- SPOJ 705 New Distinct Substrings
- SPOJ705-New Distinct Substrings-后缀数组
- [SPOJ 705] New Distinct Substrings
- SPOJ_705_New Distinct Substrings_后缀数组
- spoj -705 New Distinct Substrings--后缀数组
- SPOJ 694 Distinct Substrings + SPOJ 705 New Distinct Substrings (可重叠不相同子串个数)
- SPOJ 705 New Distinct Substrings 后缀数组
- [spoj694&spoj705]New Distinct Substrings(后缀数组)