1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <string>
5 using namespace std;
6 typedef unsigned long long ull;
7 const int N=100005,p=131;//p进制 hash
8 int T,n,ans,len1,len2;
9 ull f[N],key1[N],key2[N];
10 char s1[N],s2[N];
11 void init(){//字符串hash
12 memset(key1,0,sizeof(key1));//可以通过对二分和判定答案时边界的控制避免每次memset的耗时
13 memset(key2,0,sizeof(key2));
14 for(int i=1;i<=len1;++i){
15 key1[i]=key1[i-1]*p+(ull)s1[i];
16 }
17 for(int i=1;i<=len2;++i){
18 key2[i]=key2[i-1]*p+(ull)s2[i];
19 }
20 }
21 ull query(int flag,int pos1,int pos2){//查询两个字符串中pos1到pos2的hash值
22 if(flag==1) return key1[pos2]-key1[pos1-1]*f[pos2-pos1+1];
23 else return key2[pos2]-key2[pos1-1]*f[pos2-pos1+1];
24 }
25 int lcp(int pos1,int pos2){//二分+hash求s1串中以pos1位置开始和s2串中以pos2位置开始的lcp
26 int l=0,r=min(len1,len2);//r设的较大 貌似可以通过计算传入r 可以避免每次求hash值时memset的时间
27 while(l<r){
28 int mid=(l+r+1)>>1;//丑陋的二分写法...
29 if(mid>0&&query(1,pos1,pos1+mid-1)==query(2,pos2,pos2+mid-1)) l=mid;
30 else r=mid-1;
31 }
32 return l;
33 }
34 bool check(int pos){
35 int cnt=0,pos2=1,t;
36 while(cnt<3){//跳三次还不同说明三处以上不同
37 t=lcp(pos,pos2);//lcp
38 pos+=t+1;//这一位不同 两个指针跳到lcp后一位
39 pos2+=t+1;
40 if(pos2>len2) return true;
41 ++cnt;
42 }
43 t=lcp(pos,pos2);//最后判断一下 可能跳三次以后到达s2最后一位 恰巧相等
44 pos+=t,pos2+=t;
45 return pos2>len2;
46 }
47 int main(){
48 f[0]=1;
49 for(int i=1;i<=N;++i) f[i]=f[i-1]*p;//预处理p的幂 减少计算耗时
50 scanf("%d",&T);
51 while(T--){
52 scanf("%s",s1+1);
53 scanf("%s",s2+1);
54 len1=strlen(s1+1),len2=strlen(s2+1);
55 if(len1<len2) {//貌似不用解释了???
56 puts("0");
57 continue;
58 }
59 init();//hash 预处理
60 ans=0;
61 for(int i=1;i<=len1-len2+1;++i)//枚举每一位作为起点
62 if(check(i)) ++ans;
63 printf("%d\n",ans);
64 }
65 return 0;
66 }