题目链接:
两道模版题:
CF471Dhttp://codeforces.com/problemset/problem/471/D
POJ3461http://poj.org/problem?id=3461
KMP模版:
kuangbin:
void get_next()
{
Next[0]=-1;
int i=0,j=-1;
while(i<wlen){
while(-1!=j && w[i]!=w[j]) j=Next[j];
Next[++i]=++j;
}
}
void Searchkmp()
{
int i=0;
int j=0;
while(i<slen)
{
while(-1!=j && s[i]!=w[j])j=Next[j];
i++;j++;
if(j>=wlen){
cnt++;
j=Next[j];
}
}
}
KMP讲解1:https://www.cnblogs.com/zhangtianq/p/5839909.html
KMP讲解2:https://blog.csdn.net/f1033774377/article/details/82556438
KMP使用过程中注意模版中根据题目的细节变化
哈希讲解1:https://www.cnblogs.com/moyujiang/p/11213535.html
哈希讲解2:https://blog.csdn.net/pengwill97/article/details/80879387
哈希使用过程中一定要注意unsigned long long地方的处理(不可以小于0)
cin加快读入:ios::sync_with_stdio(false);
好几次因为多组数据cin读入导致超时。
POJ3461:
//哈希
#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<map>
#include<string.h>
using namespace std;
#define ll unsigned long long
const ll mod=1e9+7;
#define p 31
char a[1000010];
char b[1000010];
ll Hash[1000010];
ll id[1000010];
ll idx;
ll Pow[100100];
ll aim;
int main()
{
int t;
scanf("%d",&t);
Pow[0]=1;
for(int i=1;i<=100050;i++)
{
Pow[i]=Pow[i-1]*p%mod;
}
while(t--)
{
memset(Hash,0,sizeof(Hash));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
scanf("%s",a);
scanf("%s",b);
int len1=strlen(a);
aim=a[0]+1-'A';
idx=a[0]+1-'A';
for(int i=1;i<len1;i++)
{
idx=a[i]+1-'A';
aim=(aim*p+idx)%mod;
}
int len2=strlen(b);
id[0]=b[0]+1-'A';
Hash[0]=id[0];
int ans=0;
for(int i=1;i<len2;i++)
{
id[i]=b[i]+1-'A';
Hash[i]=(Hash[i-1]*p+id[i])%mod;
}
for(int i=0;i+len1-1<len2;i++)
{
ll temp;
if(i==0)
temp=Hash[len1-1]%mod;
else
temp=(Hash[i+len1-1]+mod-(Hash[i-1]*Pow[len1])%mod)%mod;
if(temp==aim)
ans++;
}
printf("%d\n",ans);
}
return 0;
}
//KMP
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
#define maxn 1000100
int Next[maxn];
string w;
string s;
int slen,wlen;
int cnt;
void get_next()
{
Next[0]=-1;
int i=0,j=-1;
/*while(i<wlen-1)
{
if(j==-1||w[i]==w[j])
{
i++;j++;
if(w[i]==w[j])
Next[i]=Next[j];
else
Next[i]=j;
}
else
j=Next[j];
}*/
while(i<wlen){
while(-1!=j && w[i]!=w[j]) j=Next[j];
Next[++i]=++j;
}
}
void Searchkmp()
{
int i=0;
int j=0;
while(i<slen)
{
while(-1!=j && s[i]!=w[j])j=Next[j];
i++;j++;
if(j>=wlen){
cnt++;
j=Next[j];
}
}
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
cin>>w;
cin>>s;
slen=s.size();
wlen=w.size();
get_next();
cnt=0;
Searchkmp();
cout<<cnt<<endl;
}
return 0;
}
CF471D
//哈希做法
#include<iostream>
#include<cstdio>
using namespace std;
#define p 31
#define ll unsigned long long
const int mod=1e9+7;
const int mod2=3145739;
int n,w;
int a[220000];
int b[220000];
int ha[220000];
int hb[220000];
int idx[220000];
ll Hash[220000];
ll Hash2[220000];
ll aHash,bHash;
int aidx;
ll qpow(ll a,ll n)
{
ll res=1;
while(n)
{
if(n&1) res=res*a%mod;
a=a*a%mod;
n>>=1;
}
return res;
}
int main()
{
cin>>n>>w;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(i>0)
ha[i]=a[i]-a[i-1];
}
for(int i=0;i<n;i++)
{
idx[i]=ha[i];
if(i==0)
{
Hash[i]=0;
//Hash2[i]=0;
}
else
{
Hash[i]=(ll)(Hash[i-1]*p+(idx[i]+mod))%mod;
//Hash2[i]=(ll)(Hash2[i-1]*p+(idx[i]+mod2))%mod2;
}
}
for(int i=0;i<w;i++)
{
scanf("%d",&b[i]);
if(i>0)
hb[i]=b[i]-b[i-1];
}
aHash=0;
for(int i=1;i<w;i++)
{
aidx=hb[i];
aHash=(ll)(aHash*p+(aidx+mod))%mod;
//bHash=((bHash*p+mod2)+(aidx+mod2))%mod2;
}
int ans=0;
ll Pow=qpow(p,w-1);
for(int i=1;i+w-2<n;i++)
{
if(aHash==((Hash[i+w-2]+mod)-(Hash[i-1]*Pow)%mod)%mod)
ans++;
}
cout<<ans<<endl;
return 0;
}
//差分+KMP
#include<iostream>
#include<cstdio>
using namespace std;
int n,w;
int a[220000];
int b[220000];
int ha[220000];
int hb[220000];
int Next[220000];
void get_next()
{
int j=0;
for(int i=2;i<w;i++)
{
while((hb[j+1]!=hb[i])&&(j>0))
j=Next[j];
if(hb[j+1]==hb[i])
j++;
Next[i]=j;
}
}
int KmpSearch()
{
int ans=0;
int i = 0;
int j = 0;
int aLen = n;
int bLen = w;
Next[0]=-1;
while (i<aLen)
{
if (j == 0||ha[i]==hb[j])
{
i++;
j++;
}
else
{
j=Next[j-1]+1;
}
if(j==bLen)
{
j=Next[j-1]+1;
ans++;
}
}
return ans;
}
int main()
{
cin>>n>>w;
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0;i<w;i++)
scanf("%d",&b[i]);
hb[0]=0;
for(int i=1;i<w;i++)
{
hb[i]=b[i]-b[i-1];
}
ha[0]=0;
for(int i=1;i<n;i++)
{
ha[i]=a[i]-a[i-1];
}
get_next();
int ans=KmpSearch();
cout<<ans<<endl;
return 0;
}