hdu_5769_Substring(后缀数组)
题目链接: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 }