spoj New Distinct Substrings
Given a string, we need to find the total number of its distinct substrings.
Input
T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000
Output
For each test case output one number saying the number of distinct substrings.
Example
Input: 2 CCCCC ABABA Output: 5 9
竟然卡log。。。害了我看了半天,改long long又tle。。。。
我不会基数排序。。。。。。。。。
n*(n+1)/2-lcp总和,因为相邻的两个sa的lcp肯定是这两个sa的最长前缀,又因为有相同前缀,肯定要减去,只用减一次就可以了,只重复了一次。。。
错误代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 50010 int n,k; int sa[N],Rank[N],temp[N],lcp[N]; char s[N]; bool cp(int i,int j) { if(Rank[i]!=Rank[j]) return Rank[i]<Rank[j]; int ri=i+k<=n?Rank[i+k]:-1; int rj=j+k<=n?Rank[j+k]:-1; return ri<rj; } void Sa() { for(int i=1;i<=n;i++) { sa[i]=i; Rank[i]=s[i]; } for(k=1;k<=n;k<<=1) { sort(sa+1,sa+n+1,cp); temp[sa[1]]=0; for(int i=2;i<=n;i++) temp[sa[i]]=temp[sa[i-1]]+(cp(sa[i-1],sa[i])); for(int i=1;i<=n;i++) Rank[i]=temp[i]; } } void Lcp() { for(int i=1;i<=n;i++) Rank[sa[i]]=i; int h=0,ans=n*(n+1)/2; for(int i=1;i<=n;i++) { int j=sa[Rank[i]-1]; if(h>0) h--; for(;(i+h<=n&&j+h<=n);h++) if(s[i+h]!=s[j+h]) break; ans-=h; } printf("%d\n",ans); } void solve() { Sa(); Lcp(); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%s",s+1); n=strlen(s+1); solve(); } return 0; }