最長異或值路徑 字典樹應用

2022-05-07 14:51:08 字數 1769 閱讀 4596

任何新型別的題,都可以轉換成自己熟悉的題來解答。

就像下面的這題:

給定乙個樹,樹上的邊都具有權值。

樹中一條路徑的異或長度被定義為路徑上所有邊的權值的異或和:

⊕ 為異或符號。

給定上述的具有n個節點的樹,你能找到異或長度最大的路徑嗎?

輸入格式

第一行包含整數n,表示樹的節點數目。

接下來n-1行,每行包括三個整數u,v,w,表示節點u和節點v之間有一條邊權重為w。

輸出格式

輸出乙個整數,表示異或長度最大的路徑的最大異或和。

資料範圍

1≤n≤100000<?xml:namespace prefix = "[default] " ns = "" />1≤n≤100000,

0≤u,v輸入樣例:

4

0 1 3

1 2 4

1 3 6

輸出樣例:
7
樣例解釋

樣例中最長異或值路徑應為0->1->2,值為7 (=3 ⊕ 4)

此題思路:

首先,這裡時求樹中的任意兩節點間的異或長度最大值,但是我們可以求出根節點到各個節點的異或和,這裡假設d[x]表示根到x的邊權所有的異或值則有

d[x] = d[father[x]] xor weight(x,fahter[x])

這裡的weight(x, father[x])表示的x到它父親邊的權值。

因此,我們轉換思路先求出每個節點到根的異或值,然後用d[i]儲存。問題就變成了,給出一段資料,求最大異或和。

這裡提示一下:

d[x] xor d[y]就是這條路徑的異或長度,因為其中重複的路徑已經通過異或的性質減去。

所以通過字典樹求出答案,和上一題的,最大異或和

差不多。

**:

1 #include 2 #include 3 #include 4

using

namespace std;56

const

int n = 1e5 + 5, m = 3e6;

7int h[n], e[n*2], c[n*2], ne[n*2], cnt, n;

8int trie[m][2], tot;

9int d[n];

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

1314

void dfs(int u, int father, int sum)

21 }

2223

void insert(int x)

30 }

3132

int query(int x)

40else p = trie[p][s];

41 }

42return res;

43 }

4445

int main()

54 dfs(0, -1, 0);

55for(int i = 0; i < n; ++ i)

56 insert(d[i]);

5758

int res = 0;

59for(int i = 0; i < n; ++ i)

60 res = max(res, query(d[i]));

61 cout << res << endl;

62return 0;

63 }

6465

最長異或路徑

題目鏈結 戳我前置知識 什麼是異或?如果二進位制下同一位不相同,則為 1 否則為 0 trie樹 基本位運算 對於同一條邊異或兩次,相當於沒有進行異或,我們將dis i 表示為從i點到根節點的路徑異或和。則問題轉化為了求兩點的dis異或最大值 貪心的想,對於乙個數x,我們對於dis i x最大,則每...

最長異或路徑 trie樹 題解

題意 給你一棵樹,有邊權,定義兩點之間的價值為這連線兩點的這條路徑上所有邊權的異或和,如1 2 1 rightarrow 2 1 2所經過的邊權為1,2 31,2,3 1,2,3,那麼1 2 1 rightarrow 2 1 2的權值就為1 2 3 3 1 bigoplus2 bigoplus3 3...

Acwing 144 最長異或值路徑

144.最長異或值路徑 給定乙個樹,樹上的邊都具有權值。樹中一條路徑的異或長度被定義為路徑上所有邊的權值的異或和 為異或符號。給定上述的具有n個節點的樹,你能找到異或長度最大的路徑嗎?輸入格式 第一行包含整數n,表示樹的節點數目。接下來n 1行,每行包括三個整數u,v,w,表示節點u和節點v之間有一...