【問題描述】
給你一棵樹,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開始向...