01Trie/可持久化01Trie学习笔记

之前一直不把Trie当回事,直到今天看了篇博客,据说01trie可以当平衡树使?然后就学了学,发现和权值线段树也没什么区别

01Trie

权值线段树的本质是一棵01Trie
01Trie就是把数字的二进制位从高到低当做字符串扔进Trie里
巨佬一眼就能看出,把最高位是0的当做左儿子,最高位是1的当做右儿子,这玩意就是权值线段树。
只是01Trie的边界有一些特性其实权值线段树也能实现,可以用来做一些按位运算的题。当然,权值线段树能实现的所有功能它都能实现。

例题:【模板】普通平衡树

做法:就和权值线段树做法是一样的。这题中平衡树能实现的功能01Trie也都能实现
妈妈再也不用教我写平衡树了
好吧平衡树还是有独特的功能的,比如区间翻转。
方法就和权值线段树实现一样。
感觉代码硬生生地比splay少了rotate和splay函数。
应该很好懂的 自认码风比较友好
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; 

const int Q = 1e7; 
struct tree
{
   
	int ch[2], size, end; 
}; 
struct Trie
{
   
	tree b[4000005]; 
	int cnt; 
	
	Trie()
	{
   
		memset(b, 0, sizeof(b)); 
		cnt = 1; 
	}
	void insert(int x)
	{
   
		int p = 1; 
		for(int i = 30; i >= 0; i--)
		{
   
			int f = ((x & (1 << i)) >> i); 
			if(!b[p].ch[f])b[p].ch[f] = ++cnt; 
			p = b[p].ch[f]; b[p].size++; 
		}
		b[p].end++; 
	}
	void del(int x)
	{
   
		int p = 1; 
		for(int i = 30; i >= 0; i--)
		{
   
			int f = ((x & (1 << i)) >> i); 
			if(!b[p].ch[f])b[p].ch[f] = ++cnt; 
			p = b[p].ch[f]; b[p].size--; 	
		}
		b[p].end--; 
	}
	int get_sum(int x)
	{
   
		int p = 1; 
		for(int i = 30; i >= 0; i--)
		{
   
			int f = ((x & (1 << i)) >> i); 
			p = b[p].ch[f]; 
			if(!p)return 0; 
		}
		return b[p].end; 		
	}
	int get_rank(int x)
	{
   
		int ret = 0, p = 1, tmp = 0; 
		for(int i = 30; i >= 0; i--)
		{
   
			int f = ((x & (1 << i)) >> i)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值