给出两个字符串s1,s2,求出s2的每一个后缀在s1中出现的次数乘以这个后缀的长度,并累加求和,输出这个和
//next[i]表示pat与pat[i,len-1]的最长公共前缀
//extend[i]表示pat与ori[i,len-1]的最长公共前缀
typedef long long ll;
const int N = 1000000 + 10, mod = 1e9 + 7;
char ori[N], pat[N];
int Next[N], extend[N];
int num[N];
int cas = 0;
void get_next(char *pat)
{
int len = strlen(pat);
Next[0] = len;
int k = 0;
while(k + 1 < len && pat[k] == pat[k+1]) ++k;
Next[1] = k;
k = 1;
for(int i = 2; pat[i]; i++)
{
if(i + Next[i-k] < k + Next[k]) Next[i] = Next[i-k];
else
{
int j = max(k + Next[k] - i, 0);
while(i + j < len && pat[j] == pat[i+j]) ++j;
Next[i] = j;
k = i;
}
}
}
void extkmp(char *ori, char *pat)
{
get_next(pat);
int leno = strlen(ori), lenp = strlen(pat);
int k = 0;
while(k < leno && k < lenp && ori[k] == pat[k]) ++k;
extend[0] = k;
k = 0;
for(int i = 1; ori[i]; i++)
{
if(i + Next[i-k] < k + extend[k]) extend[i] = Next[i-k];
else
{
int j = max(k + extend[k] - i, 0);
while(i + j < leno && j < lenp && ori[i+j] == pat[j]) ++j;
extend[i] = j;
k = i;
}
}
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%s%s", ori, pat);
int leno = strlen(ori), lenp = strlen(pat);
reverse(ori, ori + leno);
reverse(pat, pat + lenp);
extkmp(ori, pat);
memset(num, 0, sizeof num);
for(int i = 0; i < leno; i++) num[extend[i]]++;
ll ans = 0;
for(int i = lenp; i >= 1; i--)
{
num[i] += num[i+1];
ans = (ans + 1LL * num[i] * i) % mod;
}
printf("%lld\n", ans);
}
return 0;
}