码迷,mamicode.com
首页 > 编程语言 > 详细

hdu_5769_Substring(后缀数组)

时间:2016-08-02 06:34:23      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:hdu_5769_Substring

题意:

给你一个字符a和一个串b,问你有多少个包括a的字串

题解:

技术分享

技术分享
 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;++i)
 3 using namespace std;
 4 typedef long long ll;
 5 namespace suffixarray{    
 6     #define FN(n) for(int i=0;i<n;i++)
 7     const int N =1E5+7;//字符串长度
 8     int rnk[N],sa[N],height[N],c[N];char s[N];
 9     void getsa(int n,int m,int *x=rnk,int *y=height){
10         FN(m)c[i]=0;FN(n)c[x[i]=s[i]]++;FN(m)c[i+1]+=c[i];
11         for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
12         for(int k=1,p;p=0,k<=n;k=p>=n?N:k<<1,m=p){
13             for(int i=n-k;i<n;i++)y[p++]=i;
14             FN(n)if(sa[i]>=k)y[p++]=sa[i]-k;
15             FN(m)c[i]=0;FN(n)c[x[y[i]]]++;FN(m)c[i+1]+=c[i];
16             for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
17             swap(x,y),p=1,x[sa[0]]=0;
18             for(int i=1;i<n;i++)
19             x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
20         }
21         FN(n)rnk[sa[i]]=i;
22         for(int i=0,j,k=0;i<n-1;height[rnk[i++]]=k)
23         for(k=k?k-1:k,j=sa[rnk[i]-1];s[i+k]==s[j+k];k++);
24     }
25 }    
26 using namespace suffixarray;
27 int t,ic=1,nxt[N];char aim[2];
28 int main(){
29     scanf("%d",&t);
30     while(t--)
31     {
32         scanf("%s%s",aim,s),aim[0]-=a-1;
33         int len=strlen(s);
34         F(i,0,len-1)s[i]=s[i]-a+1;
35         getsa(len+1,27);
36         for(int i=len-1,x=len;i>=0;i--)
37         {
38             if(s[i]==aim[0])x=i;
39             nxt[i]=x;
40         }
41         ll ans=0;
42         F(i,1,len)ans+=len-max(nxt[sa[i]],sa[i]+height[i]);
43         printf("Case #%d: %lld\n",ic++,ans);
44     }
45     return 0;
46 }
View Code

 

hdu_5769_Substring(后缀数组)

标签:

原文地址:http://www.cnblogs.com/bin-gege/p/5727816.html

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