数据结构——字典树 刷题小记

Acwing 142. 前缀统计

题目

142. 前缀统计

算法分析

详见 这篇文章

C++ Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define rg register
typedef long long ll;
using namespace std;
inline int sread()
{
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0') {if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
	return f*x; 
}
const int maxn=1000010;
int trie[maxn][26],tail[maxn],tot=0;
int n,m,len;
char c[maxn];

void _insert(char c[])
{
	int p=0;
	for(rg int i=0;i<len;++i)
	{
		int ch=c[i]-'a';
		if(trie[p][ch]==0) trie[p][ch]= ++tot;
		p=trie[p][ch];
	}
	tail[p]++;
}

int _search(char c[])
{
	int p=0,ans=0;
	for(int i=0;i<len;++i)
	{
		p=trie[p][c[i]-'a'];
		if(p==0) return ans;
		ans+=tail[p];
	}
	return ans;
}
int main()
{
	n=sread();
	m=sread();
	for(rg int i=1;i<=n;++i)
	{
		len=0;
		while((c[len]=getchar())!='\n') len++;
		_insert(c);
	}
	for(rg int i=1;i<=m;++i)
	{
		len=0;
		while((c[len]=getchar())!='\n') len++;
		int ans= _search(c);
		printf("%d\n",ans);
	}
	return 0;
}

Acwing 143. 最大异或对

题目

143. 最大异或对

算法分析

在检索字典树的过程中,每一次都尝试沿着与当前位相反的指针向下询问,若无则向下询问即可。

C++ Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define rg register
typedef long long ll;
using namespace std;
inline int sread()
{
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0') {if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
	return f*x; 
}
const int maxn=1000010;
int trie[10*maxn][3],tot=0;
int n,m,a[maxn],ans;
void _insert(int x)
{
	int p=0;
	for(rg int i=31;i>=0;i--)
	{
		int ch=x>>i&1;
		if(trie[p][ch]==0) trie[p][ch]= ++tot;
		p=trie[p][ch];
	}
}

int _search(int x)
{
	int p=0,ans=0;
	for(int i=31;i>=0;i--)
	{
		int ch=x>>i&1;
		if(trie[p][!ch]!=0) //存在相反的 
		{
			p=trie[p][!ch];
			ans=ans*2+1;//相当于左移一位再加 1 
		}
		else 
		{
			p=trie[p][ch];
			ans=ans*2;//仅左移一位 
		}
	}
	return ans;
}

int maxx(int a,int b)
{
	return a>b?a:b;
}
int main()
{
	n=sread();
	for(rg int i=1;i<=n;++i)
	{
		a[i]=sread();
		_insert(a[i]);
	}
	for(rg int i=1;i<=n;++i)
	{
		ans=maxx(ans,_search(a[i]));
	}
	printf("%d\n",ans);
	return 0;
}

在此之外还学习了可持续化Trie,详细讲解可见 这篇文章

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值