HDU 4575 Tree(可持久化字典樹)

2021-08-07 20:00:52 字數 1923 閱讀 6509

點我看題

題意:給出一顆樹,每棵樹上有n個結點,每個結點對應乙個值,有m組查詢操作,查詢在從x到y的這條路徑上與z進行異或的最大值。

分析:可持久化字典樹的模板題

這個題以01字典樹為基礎,如果不是很了解01字典樹的話,可以看看acdream1063,這題題解。

話說回來,如果我們要查詢數x與某個數異或的最大值,我們應該盡量選擇高位與x的高位相反的一些數。

舉個栗子,我們要求5與某個數異或的最大值,假設可選的數不超過15,5的二進位制為0101,因為可選的數不超過15,所以我們只要考慮後四位,

首先看最高位(第四位)存不存在等於1的數,存在的話,一直往低位走,最終可以得到結果。

這個題就要對每個結點都建一棵trie樹(感覺根主席樹有點像噢,主席樹是對每個結點建線段樹

建trie樹的時候,我們用乙個陣列sz記錄字典樹對應結點字首的數量,如果v是u的子節點,且v的權值是010,u的權值為011,假設u已經加到樹中,那麼在加v的時候,發現字首01的數量已經是1了,那我們只要在這個基礎上加1即可,也就是繼承了父節點對它的影響,但是對於010來說是乙個新的數,我們要新建乙個結點然後更新他的sz,其餘和父節點一致就好。

當我們去查詢每一位都取反的x時,只關心每一位是否對應存在。也就是想知道u到v這條路上有沒有滿足條件的存在。

設pre=lca(u,v),我們就只要判斷f(u)+f(v)-2×f(pre)是否大於0就好,大於0的話,就加上1>>i。

/*可持久化字典樹*/

#include#include#include#include#include#includeusing namespace std;

#define mem(a,b) memset(a,b,sizeof(a))

const int maxn = 1e5+10;//原樹結點

const int maxv = 16;//每顆字典樹的深度

const int maxnode = 2e6;//字典樹的結點個數,16*1e5=1600000

int n,q;

int a[maxn];

vectorg[maxn];

//字典樹

int tot;//記錄字典樹的總結點數

int root[maxn];//記錄字典樹的根節點

int f[maxv+2][maxn];//嘻嘻嘻嘻f[i][v]指的是結點v向上跳2^i次後得到的結點值

int sz[maxnode];//記錄字首和

int dep[maxn];//記錄結點深度

int ch[maxnode][2];//字典樹兒子結點

void init()

int newnode()

void insert( int u, int fa, int val)

rtu = ch[rtu][id];//往下走

rtf = ch[rtf][id];

sz[rtu]++;

}}//遍歷原樹中的n個結點,對每個結點建立01字典樹

void dfs( int u, int fa)

}//倍增lca

//求u和v的最近公共祖先

int lca( int u, int v)

int query( int u, int v, int val)

{ int f = lca(u,v);//求u,v的最近公共祖先

int res = a[f]^val;

int rtu = root[u], rtv = root[v], rtf = root[f];//轉化到字典樹中去

int ret = 0;

for( int i = maxv-1; i >= 0; i--)

{int id = (val>>i)&1;

if( sz[ch[rtu][!id]]+sz[ch[rtv][!id]]-2*sz[ch[rtf][!id]] > 0)//滿足這個條件

{ret += 1<

可持久化Trie HDU4757 Tree

恩,剛學了一發可持久化trie樹,其實挺簡單的。反正可持久化資料結構都乙個樣嘛,動態加點就好了。還是寫一篇部落格給自己看吧。因為樹上的路徑嘛,肯定要想到把路徑分成兩部分,x lca x,y 和 y lca x,y 這就相當與兩塊區間,然後求單點異或最大值,自然就想到可持久化了唄。想想你怎麼用可持久化...

可持久化Treap

本來是想寫一點題的,但是hfu最近讓我改鍵盤指法,原來都是亂打 手速蠻快就是錯的多 剛開始練手法真的煩躁,像我這種從來不用小指頭的 就寫個學習筆記吧.非教程向,只是懂了後寫點隨筆,練成指法說不定能來填坑.可持久化treap首先是基於非旋轉式treap的,如果要旋轉的話那麼就會破壞父子關係導致無法可持...

可持久化Treap

可持久化treap本質上市乙個二叉平衡樹,若不對其規則進行修改,中序遍歷後得出的序列是遞增的。void maintain o 計算結點o的size int lowcount key 比key所在位置小1 int uppercount key key所在的位置,如果有多個相同的key,選位置最大的 i...