poj 3764 最長異或路徑 二進位制trie樹)

2021-07-28 04:21:17 字數 1494 閱讀 3602

【問題描述】

給你一棵樹,n個節點,n-1條邊每條邊i都有乙個權值wi。定義任意兩點間的權值為:這兩點間的路徑上的所有邊的值的異或。比如a點和b點間有i,j,k三條邊,那麼ab兩點間的權值為:wi^wj^wk。求這個最大的權值(最長異或路徑)。

【輸入格式】

第一行為n表示節點數目(節點編號為1..n)。

接下來的n-1行,每行三個整數:u v w,表示一條樹邊(x,y)的權值為w(0<=w<2^31)。

【輸出格式】

輸出最長異或路徑長度。

【輸入樣例】

4 1 2 3

2 3 4

2 4 6

【輸出樣例】

【樣例解釋】

the xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)

【資料範圍】

n<=250000

【**】

poj 3764

這道題都能想到用dfs來生成根到每乙個點的異或路徑,但生成之後的操作就是重點了。

首先我們可以很容易的想到任意2個點直接的異或路徑就是他們到跟的異或路徑的異或值,證明如下:

設2點為x,y,公共祖先是z。z到根的異或路徑是c,x到z的異或路徑是a,y到z的異或路徑是b。可得a^b=a^c^b^c。

不用二進位制trie樹的話很容易想到乙個n^2時間複雜的演算法,就是每2個數進行異或。但如果有了二進位制trie樹就可以先生成樹,在再樹上貪心的進行查詢,很容易就可以得到最大值了,時間複雜度(n*log2n)。

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=250005;

struct edge

e[maxn];

int d[maxn],f[maxn]=,ch[maxn*33][2]=,cnt=0,tot=0,n;

int a[33];

bool vis[maxn*33]=,usd[maxn]=;

void in(int x)

vis[p]=1;

}void add(int u,int v,int w)

;f[u]=tot;

}int read()

return x;

}void dfs(int i)

}int find(int x)

return x;

}int main()

in(0);

for(int i=1;i<=n;i++)if(!usd[i])

dfs(i);

int ans=0;

for(int i=1;i<=n;i++)

ans=max(ans,find(d[i]));

cout

0;}

異或與二進位制

baobao has a sequence a 1 a 2 a n he would like to find a subset sof such that i j s a i a j a i a j and s is maximum,where means bitwise exclusive or...

二進位制位運算(與 或 異或 取反)

1.與運算 and 0 and 0 0 全1才1 1 and 0 0 0 and 1 0 1 and 1 1 用途 用來位置0,若想把ffh 11111111b,255d 第 三 五 從右往左 位置0,只需 and 11101011b 235d,e8h 2.或運算 or 0 or 0 0 全0才0 ...

二進位制亂搞 Luogu3917 異或序列

題面 luogu3917 我的做法好像比較傻。看到這種題首先想到字首。首先字首xor是不是很資辭?我的做法呢就是先把所有數按二進位制位拆開,然後每一位都做兩次字首。首先對數字做一次字首xor,記到 s 陣列裡,再對s陣列做一次字首和,記到ss 裡。然後我們可以對於每一位列舉起始位置i,然後從i開始向...