哈希 kmp trie树

哈希

定义

image
hash方式

image

hash公式

image

单hash方法

image

image

双hash方法

image

获取子串的hash

image

代码

#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
image

image

image

image

image

image

image

image

image

image

kmp优化

image

image

image
代码

#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 树

image

image

代码

#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树

image

image

image

image

代码

#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. }}\)

posted @ 2025-07-28 07:47  BIxuan—玉寻  阅读(23)  评论(1)    收藏  举报