next数组表示该位置最长前缀后缀
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <cstring>
#include <stdio.h>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <string>
#define MAX 1000010
#define INF 0x3f3f3f3f
#define EXP 1e-9
using namespace std;
typedef long long ll;
int n;
char s[MAX];
char w[MAX];
int f[MAX];
int main(){
scanf("%d",&n);
while(n--){
scanf(" %s",s);
scanf(" %s",w);
int ls=strlen(s);
int lw=strlen(w);
f[0]=-1;
for(int i=1;i<ls;i++){
int j=f[i-1];
while((s[j+1]!=s[i])&&(j>=0))
j=f[j];
if(s[j+1]==s[i])f[i]=j+1;
else f[i]=-1;
}
//for(int i=0;i<ls;i++){
// printf("%d ++\n",f[i]);
//}
int i=0,j=0,ans=0;
while(i<lw){
if(w[i]==s[j]){
i++;
j++;
if(j==ls){
j=f[j-1]+1;
ans++;
}
}
else {
if(j==0)i++;
else j=f[j-1]+1;
}
}
printf("%d\n",ans);
}
return 0;
}
next数组表示下一位最长前缀后缀
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <cstring>
#include <stdio.h>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <string>
#define MAX 1000010
#define INF 0x3f3f3f3f
#define EXP 1e-9
using namespace std;
typedef long long ll;
int t;
char s[MAX];
char w[MAX];
int f[MAX];
int main(){
scanf("%d",&t);
while(t--){
scanf(" %s %s",s,w);
int ls=strlen(s);
int lw=strlen(w);
f[0]=f[1]=0;
for(int i=1;i<ls;i++){
int j=f[i];
while(j&&s[i]!=s[j])
j=f[j];
f[i+1]= s[i]==s[j]?j+1:0;
}
//for(int i=0;i<=ls;i++){
// printf("%d +++\n",f[i]);
//}
int i=0,j=0,ans=0;
for(;i<lw;i++){
//printf("%d %d +++",i,j);
while(j&&w[i]!=s[j])
j=f[j];
if(s[j]==w[i])j++;
if(j==ls)j=f[j],ans++;
}
printf("%d\n",ans);
}
return 0;
}