您的位置:首页 > 其它

hdu_5769_Substring(后缀数组)

2016-08-02 00:50 369 查看

题目链接:hdu_5769_Substring

题意:

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

题解:

#include<bits/stdc++.h>
#define F(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
typedef long long ll;
namespace suffixarray{
#define FN(n) for(int i=0;i<n;i++)
const int N =1E5+7;//字符串长度
int rnk
,sa
,height
,c
;char s
;
void getsa(int n,int m,int *x=rnk,int *y=height){
FN(m)c[i]=0;FN(n)c[x[i]=s[i]]++;FN(m)c[i+1]+=c[i];
for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
for(int k=1,p;p=0,k<=n;k=p>=n?N:k<<1,m=p){
for(int i=n-k;i<n;i++)y[p++]=i;
FN(n)if(sa[i]>=k)y[p++]=sa[i]-k;
FN(m)c[i]=0;FN(n)c[x[y[i]]]++;FN(m)c[i+1]+=c[i];
for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
swap(x,y),p=1,x[sa[0]]=0;
for(int i=1;i<n;i++)
x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
}
FN(n)rnk[sa[i]]=i;
for(int i=0,j,k=0;i<n-1;height[rnk[i++]]=k)
for(k=k?k-1:k,j=sa[rnk[i]-1];s[i+k]==s[j+k];k++);
}
}
using namespace suffixarray;
int t,ic=1,nxt
;char aim[2];
int main(){
scanf("%d",&t);
while(t--)
{
scanf("%s%s",aim,s),aim[0]-='a'-1;
int len=strlen(s);
F(i,0,len-1)s[i]=s[i]-'a'+1;
getsa(len+1,27);
for(int i=len-1,x=len;i>=0;i--)
{
if(s[i]==aim[0])x=i;
nxt[i]=x;
}
ll ans=0;
F(i,1,len)ans+=len-max(nxt[sa[i]],sa[i]+height[i]);
printf("Case #%d: %lld\n",ic++,ans);
}
return 0;
}
View Code  

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: