1. 程式人生 > >spoj 694 求一個字串中不相同子串的個數

spoj 694 求一個字串中不相同子串的個數

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

【分析】
嗯…參考 論文

…nei個神奇的spoj交不了題…所以現在暫時未通過…我把樣例過了假裝自己A了吧

【程式碼】

#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=100005;
int a[mxn],b[mxn],x[mxn],y[mxn],sa[mxn],rank[mxn],height[mxn];
char
s[mxn]; int n,m,len,T; inline bool comp(int i,int j,int l) { return y[i]==y[j]&&(i+l>len?-1:y[i+l])==(j+l>len?-1:y[j+l]); } inline void work() { int i,j,k,p; fo(i,0,m) b[i]=0; fo(i,1,len) b[x[i]=a[i]]++; fo(i,1,m) b[i]+=b[i-1]; for(i=len;i>=1;i--) sa[b[x[i]]--]=i; for
(k=1;k<=len;k<<=1) { p=0; //處理第二關鍵字 fo(i,len-k+1,len) y[++p]=i; fo(i,1,len) if(sa[i]>k) y[++p]=sa[i]-k; //處理第一關鍵字 fo(i,0,m) b[i]=0; fo(i,1,len) b[x[y[i]]]++; fo(i,1,m) b[i]+=b[i-1]; for(i=len;i>=1;i--) sa[b[x[y[i]]]--]=y[i]; swap(x,y),p=2,x[sa[1]]=1; fo(i,2,len) x[sa[i]]=comp(sa[i-1],sa[i],k)?p-1:p++; if(p>len) break; m=p; } p=k=0; fo(i,1,len) rank[sa[i]]=i; for(i=1;i<=len;height[rank[i++]]=k) for(k?k--:0,j=sa[rank[i]-1];a[i+k]==a[j+k];k++); } int main() { int i,j,ans; scanf("%d",&T); while(T--) { M(a);M(sa); ans=0; m=129; scanf("%s",s+1); len=strlen(s+1); fo(i,1,len) a[i]=s[i]; work(); fo(i,1,len) ans+=len-sa[i]+1-height[i]; printf("%d\n",ans); } return 0; } /* 2 CCCCC */