码迷,mamicode.com
首页 > 其他好文 > 详细

SPOJ - DISUBSTR Distinct Substrings

时间:2017-10-09 23:57:37      阅读:390      评论:0      收藏:0      [点我收藏+]

标签:space   字符   substr   个数   turn   sub   names   swa   log   

题意:给一个字符串,求它不同的子串的个数

方法:后缀数组,答案是sum(n-sa[i]+height[i])

代码:

 1 #include<iostream>
 2 using namespace std;
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 const long long maxn=20010;
 7 long long t1[maxn],t2[maxn],c[maxn];
 8 bool cmp(long long *r,long long a,long long b,long long i){
 9     return r[a]==r[b]&&r[a+i]==r[b+i];
10 }
11 void da(char str[],long long sa[],long long RANKP[],long long height[],long long n,long long m){
12     n++;
13     long long i,j,p,*x=t1,*y=t2;
14     for (i=0;i<m;i++) c[i]=0;
15     for (i=0;i<n;i++) c[x[i]=str[i]]++;
16     for (i=0;i<m;i++) c[i]+=c[i-1];
17     for (long long i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
18     for (j=1;j<=n;j<<=1){
19         p=0;
20         for (i=n-j;i<n;i++) y[p++]=i;
21         //for (i=n-1;i>=n-j;i--) y[p++]=i;
22         for (i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j;
23         for (i=0;i<m;i++) c[i]=0;
24         for (i=0;i<n;i++) c[x[y[i]]]++;
25         for (i=1;i<m;i++) c[i]+=c[i-1];
26         for (i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
27         swap(x,y);
28         p=1;x[sa[0]]=0;
29         for (i=1;i<n;i++)
30             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
31         if (p>=n) break;
32         m=p;
33     }
34     long long k=0;
35     n--;
36     for (i=0;i<=n;i++) RANKP[sa[i]]=i;
37     for (i=0;i<n;i++){
38         if (k) k--;
39         j=sa[RANKP[i]-1];
40         while(str[i+k]==str[j+k]) k++;
41         height[RANKP[i]]=k;
42     }
43 }
44 long long RANKP[maxn],height[maxn];
45 long long RMQ[maxn];
46 long long mm[maxn];
47 char str[maxn];
48 long long sa[maxn];
49 long long getans(long long n){
50     long long ans=0;
51     ans+=n-sa[1];
52     for (long long i=2;i<=n;i++){
53     ans+=n-sa[i]-height[i];
54     }
55     return ans;
56 }
57 void deal(){
58     scanf("%s",str);
59     //cout<<"OK";
60     long long n=strlen(str);
61     str[n]=0;
62     da(str,sa,RANKP,height,n,200);
63    // for (int i=1;i<=n;i++) printf("%d %d %s\n",i,sa[i],str+sa[i]);
64     long long ans;
65     ans=getans(n);
66     printf("%lld\n",ans);
67 }
68 int main(){
69     long long t;
70     scanf("%lld",&t);
71     while(t--) deal();
72     return 0;
73 }

 

SPOJ - DISUBSTR Distinct Substrings

标签:space   字符   substr   个数   turn   sub   names   swa   log   

原文地址:http://www.cnblogs.com/xfww/p/7643288.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!