1. 程式人生 > >hdu 6068 Classic Quotation(字符串hash)

hdu 6068 Classic Quotation(字符串hash)

images 兩個 for init prev %d closed lin image

題目鏈接:hdu 6068 Classic Quotation

題意:

給你兩個字符串S和T,現在有q個詢問,每個詢問給出一個l,r,問S[1..i]技術分享S[j..n](1iL,Rjn)中有多少個T,求出全部的總和。

題解:

Claris的官方題解:

技術分享

這裏我用hash代替了kmp的作用。

技術分享
 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 using ull = unsigned long
long ; 6 7 const int N=5e4+7; 8 int t,n,m,q,pre[N][101],suf[N][101],L[N],R[N],l,r; 9 char S[N],T[N]; 10 ull b[N]; 11 struct string_hash 12 { 13 static const int seed=131; 14 ull h[N]; 15 inline int idx(char x){return x-a+1;} 16 static void init(){b[0]=1;F(i,1,N-1)b[i]=b[i-1]*seed;}
17 void ins(char *s,int len) 18 { 19 h[0]=1; 20 F(i,1,len)h[i]=h[i-1]*seed+idx(s[i]); 21 } 22 inline ull ask(int l,int r){return h[r]-b[r-l+1]*h[l-1];} 23 }A,B; 24 25 int main(){ 26 scanf("%d",&t); 27 string_hash::init(); 28 while(t--) 29 { 30 scanf("
%d%d%d",&n,&m,&q); 31 scanf("%s%s",S+1,T+1); 32 A.ins(S,n),B.ins(T,m); 33 F(i,1,n)for(int l=1,en=min(m,i);l<=en;++l) 34 pre[i][l]=(A.ask(i-l+1,i)==B.ask(1,l)); 35 reverse(S+1,S+n+1),reverse(T+1,T+m+1); 36 A.ins(S,n),B.ins(T,m); 37 F(i,1,n)for(int l=1,en=min(m,i);l<=en;++l) 38 suf[i][l]=(A.ask(i-l+1,i)==B.ask(1,l)); 39 for(int i=1,cnt=0;i<=n;++i) 40 cnt+=pre[i][m],L[i]=L[i-1]+cnt; 41 for(int i=1,cnt=0;i<=n;++i) 42 cnt+=suf[i][m],R[i]=R[i-1]+cnt; 43 F(i,1,n)F(j,1,m) 44 pre[i][j]+=pre[i-1][j],suf[i][j]+=suf[i-1][j]; 45 while(q--) 46 { 47 scanf("%d%d",&l,&r);r=n-r+1; 48 ll ans=1ll*L[l]*r+1ll*R[r]*l; 49 F(i,1,m-1)ans+=1ll*pre[l][i]*suf[r][m-i]; 50 printf("%lld\n",ans); 51 } 52 } 53 return 0; 54 }
View Code

hdu 6068 Classic Quotation(字符串hash)