任何新型別的題,都可以轉換成自己熟悉的題來解答。
就像下面的這題:
給定乙個樹,樹上的邊都具有權值。
樹中一條路徑的異或長度被定義為路徑上所有邊的權值的異或和:
⊕ 為異或符號。
給定上述的具有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 4using
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之間有一...