DreamGrid has two strings and . He would like to ask several questions about the value of , where is the substring of starting from with length and is a given number.
Input
There are multiple test cases. The first line of input contains an integer , indicating the number of test cases. For each test case:
The first line contains three integers and and () -- the length of , the length of and the number of questions.
The second line contains lowercase English letters denoting the string . The third line contains lowercase English letters denoting the string .
Each of the next lines contains two integers and () denoting the -th question.
It is guaranteed that neither the sum of all nor the sum of all exceeds .
Output
For each question, output an integer denoting the answer.
Sample Input
1 4 2 3 abcd ba 1 2 2 2 3 2
Sample Output
最后,经过归纳,我们发现这两种情况可以统一,对于不循环的单词,我可以把他的循环节看作是整个串,即loop=len。这样结论就是(n-i)/loop+1,这个i就是最小拼接点。具体实现的话,可以考虑用字符串hash来解决,但是实现过程种发现数据卡hash,如果你使用ULL自动对2^64取模,那么很遗憾会被卡掉。只有当利用两个质数hash的时候才能够AC。具体见代码:
#include<bits/stdc++.h>
#define LL long long
#define N 200010
using namespace std;
struct String_Hash
{
LL Hs[N],hs[N],p[N],P[N];
const LL mod=100001651,MOD=100001623;
void ins(char *s)
{
p[0]=P[0]=1;
Hs[0]=hs[0]=s[0]-'a'+1;
for(int i=1;s[i];i++)
{
Hs[i]=(Hs[i-1]*111%MOD+s[i]-'a'+1)%MOD;
hs[i]=(hs[i-1]*100007%mod+s[i]-'a'+1)%mod;
P[i]=P[i-1]*111%MOD;p[i]=p[i-1]*100007%mod;
}
}
pair<LL,LL> Hash(int l,int r)
{
LL tmp1=Hs[r],tmp2=hs[r];
if (!l) return make_pair(tmp1,tmp2);
tmp1=(tmp1-Hs[l-1]*P[r-l+1]%MOD+MOD)%MOD;
tmp2=(tmp2-hs[l-1]*p[r-l+1]%mod+mod)%mod;
return make_pair(tmp1,tmp2);
}
} S,T;
map< pair<LL,LL>, int > mp;
char s[N],t[N];
int Next[N],m;
void getNext()
{
Next[0]=-1;
for (int i=1;i<=m;i++)
{
int p=Next[i-1];
while (p>=0 && t[p+1]!=t[i]) p=Next[p];
Next[i]=p+1;
}
}
int main()
{
int T_T;
scanf("%d",&T_T);
while(T_T--)
{
int n,q;LL loop;
scanf("%d%d%d%s%s",&n,&m,&q,s+1,t+1);
getNext(); loop=m-Next[m];
if (Next[m]*2<m) loop=m;
for(int i=m+1;i<=2*m;i++) t[i]=t[i-m];
S.ins(s+1); T.ins(t+1); mp.clear();
for(int i=0;i<m;i++)
{
pair<LL,LL> tmp;
tmp=T.Hash(m-i,2*m-i-1);
mp[tmp]=m-i;
}
while(q--)
{
int k; LL len,tp;
scanf("%d%lld",&k,&len);
pair<LL,LL> tmp;
tmp=S.Hash(k-1,k+m-2);
if (mp[tmp])
{
tp=mp[tmp];
if (len>=tp) printf("%lld\n",(len-tp)/loop+1LL);
else puts("0");
} else puts("0");
}
}
return 0;
}