Classic Quotation
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Problem Description
When
online chatting, we can save what somebody said to form his ''Classic
Quotation''. Little Q does this, too. What's more? He even changes the
original words. Formally, we can assume what somebody said as a string S whose length is n. He will choose a continuous substring of S(or choose nothing), and remove it, then merge the remain parts into a complete one without changing order, marked as S′. For example, he might remove ''not'' from the string ''I am not SB.'', so that the new string S′ will be ''I am SB.'', which makes it funnier.
After doing lots of such things, Little Q finds out that string T occurs as a continuous substring of S′ very often.
Now given strings S and T, Little Q has k questions. Each question is, given L and R, Little Q will remove a substring so that the remain parts are S[1..i] and S[j..n], what is the expected times that T occurs as a continuous substring of S′ if he choose every possible pair of (i,j)(1≤i≤L,R≤j≤n) equiprobably? Your task is to find the answer E, and report E×L×(n−R+1) to him.
Note : When counting occurrences, T can overlap with each other.
After doing lots of such things, Little Q finds out that string T occurs as a continuous substring of S′ very often.
Now given strings S and T, Little Q has k questions. Each question is, given L and R, Little Q will remove a substring so that the remain parts are S[1..i] and S[j..n], what is the expected times that T occurs as a continuous substring of S′ if he choose every possible pair of (i,j)(1≤i≤L,R≤j≤n) equiprobably? Your task is to find the answer E, and report E×L×(n−R+1) to him.
Note : When counting occurrences, T can overlap with each other.
Input
The first line of the input contains an integer C(1≤C≤15), denoting the number of test cases.
In each test case, there are 3 integers n,m,k(1≤n≤50000,1≤m≤100,1≤k≤50000) in the first line, denoting the length of S, the length of T and the number of questions.
In the next line, there is a string S consists of n lower-case English letters.
Then in the next line, there is a string T consists of m lower-case English letters.
In the following k lines, there are 2 integers L,R(1≤L<R≤n) in each line, denoting a question.
In each test case, there are 3 integers n,m,k(1≤n≤50000,1≤m≤100,1≤k≤50000) in the first line, denoting the length of S, the length of T and the number of questions.
In the next line, there is a string S consists of n lower-case English letters.
Then in the next line, there is a string T consists of m lower-case English letters.
In the following k lines, there are 2 integers L,R(1≤L<R≤n) in each line, denoting a question.
Output
For each question, print a single line containing an integer, denoting the answer.
Sample Input
1
8 5 4
iamnotsb
iamsb
4 7
3 7
3 8
2 7
Sample Output
1
1
0
0
分析:首先,对于某一对(l,r),我们可以求出答案为preg l + suf r,pref l;
其中preg表示前缀l中T的个数,pref l表示匹配完前缀l指针所在位置,suf r,pref l表示从r开始的后缀中从pref l指针开始匹配得到的T的个数;
因为要求所有的贡献和,l<=L,r>=R,所以考虑前缀和与后缀和;
ans=∑i=1~L∑j=R~n pregi + sufj,prefi=(n−R+1)pregL+∑i=0~m−1 sL,i×sufR,i
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <bitset> #include <map> #include <queue> #include <stack> #include <vector> #include <cassert> #include <ctime> #define rep(i,m,n) for(i=m;i<=(int)n;i++) #define mod 998244353 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define sys system("pause") #define ls rt<<1 #define rs rt<<1|1 #define all(x) x.begin(),x.end() const int maxn=5e4+10; const int N=5e4+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qmul(ll p,ll q,ll mo){ll f=0;while(q){if(q&1)f=(f+p)%mo;p=(p+p)%mo;q>>=1;}return f;} ll qpow(ll p,ll q,ll mo){ll f=1;while(q){if(q&1)f=qmul(f,p,mo)%mo;p=qmul(p,p,mo)%mo;q>>=1;}return f;} int n,m,k,t,nxt[maxn],nxt1[110][26]; ll pref[maxn],preg[maxn],s[maxn][110],suf[maxn][110]; char a[maxn],b[maxn]; void init(char *a,char *b) { for(int i=0;i<=n;i++) { pref[i]=preg[i]=0; for(int j=0;j<=m;j++) { s[i][j]=suf[i][j]=0; } } nxt[0]=-1; int j=-1; for(int i=0;i<=m;i++) { while(!(j==-1||b[j]==b[i]))j=nxt[j]; nxt[i+1]=++j; } j=0; for(int i=0;i<n;i++) { while(!(j==-1||a[i]==b[j]))j=nxt[j]; if(i)preg[i]=preg[i-1]; pref[i]=++j; s[i][j]++; if(j==m)preg[i]++; } for(int i=1;i<n;i++) { preg[i]+=preg[i-1]; for(int j=0;j<=m;j++) { s[i][j]+=s[i-1][j]; } } for(int i=0;i<=m;i++) { for(int j='a';j<='z';j++) { int k=i; while(!(k==-1||j==b[k]))k=nxt[k]; nxt1[i][j-'a']=k+1; } } for(int i=n-1;i>=0;i--) { for(int j=0;j<=m;j++) { int tmp=nxt1[j][a[i]-'a']; suf[i][j]+=suf[i+1][tmp]; if(tmp==m)suf[i][j]++; } } for(int i=n-1;i>=0;i--) { for(int j=0;j<=m;j++) { suf[i][j]+=suf[i+1][j]; } } } int main() { int i,j; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); scanf("%s%s",a,b); init(a,b); while(k--) { int x,y; scanf("%d%d",&x,&y); ll ret=(n-y+1)*preg[x-1]; for(int i=0;i<=m;i++) { ret+=s[x-1][i]*suf[y-1][i]; } printf("%lld ",ret); } } return 0; }