哈希 kmp trie树
哈希
定义

hash方式

hash公式

单hash方法


双hash方法

获取子串的hash

代码
#include<bits/stdc++.h>
using namespace std;
char s1[1000010],s2[1000010];
unsigned h2[1000010],p2[1000010];
unsigned long long h1[1000010],p1[1000010];
unsigned g1(int l,int r)
{
return h1[r]-h1[l-1]*p1[r-l+1];
}
unsigned g2(int l,int r)
{
return h2[r]-h2[l-1]*p2[r-l+1];
}
int main()
{
int t;
cin>>t;
p1[0]=1;
p2[0]=1;
for(int i=1;i<=1000000;i++)
{
p1[i]=p1[i-1]*13331;
p2[i]=p2[i-1]*13331;
}
while(t--)
{
cin>>s1>>s2;
int len1=strlen(s1);
int len2=strlen(s2);
unsigned h1a=0,h2a=0;
for(int i=0;i<len1;i++)
{
h1a=h1a*13331+s1[i];
h2a=h2a*13331+s1[i];
}
for(int i=0;i<len2;i++)
{
h1[i+1]=h1[i]*13331+s2[i];
h2[i+1]=h2[i]*13331+s2[i];
}
int ans=0;
for(int i=1;i+len1-1<=len2;i++)
{
if(g1(i,i+len1-1)==h1a&&g2(i,i+len1-1)==h2a)
{
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}
kmp










kmp优化



代码
#include<bits/stdc++.h>
using namespace std;
int kmp[1000010];
int la,lb;
string a,b;
int main()
{
cin>>a>>b;
la=a.size();
lb=b.size();
a=' '+a;
b=' '+b;
int j=0;
for(int i=2;i<=lb;i++)
{
while(j&&b[i]!=b[j+1])
{
j=kmp[j];
}
if(b[j+1]==b[i])
{
j++;
}
kmp[i]=j;
}
j=0;
for(int i=1;i<=la;i++)
{
while(j>0&&b[j+1]!=a[i])
{
j=kmp[j];
}
if(b[j+1]==a[i])
{
j++;
}
if(j==lb)
{
cout<<i-lb+1<<endl;
j=kmp[j];
}
}
for(int i=1;i<=lb;i++)
{
cout<<kmp[i]<<" ";
}
return 0;
}
trie 树


代码
#include<bits/stdc++.h>
using namespace std;
int n;
int Trie[2010000][50],tot=1,ed[2010000];
string ss[2000100];
void insert(string str)
{
int len=str.size(),p=1;
for(int i=0;i<len;i++)
{
int ch=str[i]-'0';
if(Trie[p][ch]==0)
{
tot++;
Trie[p][ch]=tot;
}
ed[p]=0;
p=Trie[p][ch];
}
if(ed[p]!=0)
{
ed[p]=1;
}
}
int search(string str)
{
int len=str.size(),p=1;
for(int i=0;i<len;i++)
{
p = Trie[p][str[i]-'0'];
if(p==0)
{
return 0;
}
}
return ed[p];
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
memset(ed,2,sizeof(ed));
for(int i=1;i<=n;i++)
{
string s;
cin>>s;
insert(s);
ss[i]=s;
}
for(int i=1;i<=n;i++)
{
if(search(ss[i])==0)
{
cout<<"NO"<<endl;
break;
}
if(i==n)
{
cout<<"YES"<<endl;
}
}
}
return 0;
}
可持久化trie树




代码
#include<bits/stdc++.h>
using namespace std;
int n;
int t[3100000][2],tot=1,a[2010000];
int head[200010],to[2000010],ww[2000010],nxt[2000010],tott=0;
void lqx(int u,int v,int w)
{
tott++;
nxt[tott]=head[u];
to[tott]=v;
ww[tott]=w;
head[u]=tott;
}
void dfs(int x,int fa)
{
for(int i=head[x];i;i=nxt[i])
{
int v=to[i];
int w=ww[i];
if(v!=fa)
{
a[v]=a[x]^w;
dfs(v,x);
}
}
}
void insert(string str)
{
int p=0;
for(int i=0;i<32;i++)
{
int ch=str[i]-'0';
if(t[p][ch]==0)
{
tot++;
t[p][ch]=tot;
}
p=t[p][ch];
}
}
int search(string str)
{
int root=0,ans=0,o=0;
for(int i=0;i<32;i++)
{
o=str[i]-'0';
if(t[root][!o])
{
ans+=1<<(31-i);
root=t[root][!o];
}
else
{
root=t[root][o];
}
}
return ans;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<n;i++)
{
int u,v,w;
cin>>u>>v>>w;
lqx(u,v,w);
lqx(v,u,w);
}
dfs(1,-1);
for(int i=1;i<=n;i++)
{
int x;
x=a[i];
std::bitset<32> s(x);
insert(s.to_string());
}
int ans=0;
for(int i=1;i<=n;i++)
{
int x=a[i];
std::bitset<32> s(x);
string ss=s.to_string();
ans=max(search(ss),ans);
}
cout<<ans;
return 0;
}
\({\cal {The }}\) \({\cal {end. }}\)
以下是签名
${\scr {jade }}$ ${\scr {seek }}$
本文来自博客园,作者:BIxuan—玉寻,转载请注明原文链接:https://www.cnblogs.com/zhangyuxun100219/p/19008223

浙公网安备 33010602011771号