P2420 讓我們異或吧 異或性質 樹形結構

2021-08-27 20:35:13 字數 2084 閱讀 1412

題目鏈結異或是一種神奇的運算,大部分人把它總結成不進製加法.

在生活中…xor運算也很常見。比如,對於乙個問題的回答,是為1,否為0.那麼:

(a是否是男生 )xor( b是否是男生)=a和b是否能夠成為情侶

好了,現在我們來製造和處理一些複雜的情況。比如我們將給出一顆樹,它很高興自己有n個結點。樹的每條邊上有乙個權值。我們要進行m次詢問,對於每次詢問,我們想知道某兩點之間的路徑上所有邊權的異或值。

輸入格式:

輸入檔案第一行包含乙個整數n,表示這顆開心的樹擁有的結點數,以下有n-1行,描述這些邊,每行有3個數,u,v,w,表示u和v之間有一條權值為w的邊。接下來一行有乙個整數m,表示詢問數。之後的m行,每行兩個數u,v,表示詢問這兩個點之間的路徑上的權值異或值。

輸出格式:

輸出m行,每行乙個整數,表示異或值

輸入樣例#1:複製

5

1 4 9644

2 5 15004

3 1 14635

5 3 9684

32 4

5 41 1

輸出樣例#1:複製

975

14675

0

對於40%的資料,有1 ≤ n,m ≤ 3000;

對於100%的資料,有1 ≤ n ,m≤ 100000。

這道題看著很可怕,又是異或又是樹什麼的。鑑於異或的特殊性,我google了下異或是否有逆運算,了解了這些公式:

a ^ 0 = a

a ^ a = 0

a ^ b = c -> a = b ^ c -> b = a ^ c

於是我就想,如果我們求的圖形不是樹,而是簡單的鏈狀結構,那麼結合上面的公式,豈不是可以很簡單地用字首異或與差分的思想來解決?

但這是樹啊,於是我另闢蹊徑。

也許是樹鏈剖分?也許要用lca?然而我都不會。

但是!解題的關鍵恰恰是看似把題目複雜化了的xor運算!此題的最簡單解法就是用字首異或與差分的思想

異或運算xor滿足交換律和結合律。

以任意結點為根節點,從該節點遍歷其他結點,算出路徑上邊權的異或值。那麼考慮這種一般情況,結點4和結點5有最近公共祖先(lca)結點3,那麼根節點1到4的異或值為x1,4, 1到5的異或值為x1,5, 1到3的異或值為x1,3,我們要求的是從結點4到5的異或值。

有如下幾個式子:

x1,3 ^ x3,4 = x1,4 -> x3,4 = x1,3 ^ x1,4

x1,3 ^ x3,5 = x1,5 -> x3,5 = x1,3 ^ x1,5

x4,5 = x3,4 ^ x3,5 = x1,3 ^ x1,4 ^ x1,3 ^ x1,5 = x1,4 ^ x1,5

於是,要求出從結點4到結點5的異或值,只要異或從根結點到結點4和結點5的異或值。

#include 

#include

using

namespace

std;

struct node

};const

int maxn = 100005;

int n, m;

vector

g[maxn];

int xo[maxn] = {};

bool vis[maxn] = {};

void dfs(int u)

}}int main()

vis[1] = true;

dfs(1);

cin >> m;

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

}

P2420 讓我們異或吧

p2420 讓我們異或吧異或是一種神奇的運算,大部分人把它總結成不進製加法.在生活中 xor運算也很常見。比如,對於乙個問題的回答,是為1,否為0.那麼 a是否是男生 xor b是否是男生 a和b是否能夠成為情侶 好了,現在我們來製造和處理一些複雜的情況。比如我們將給出一顆樹,它很高興自己有n個結點...

P2420 讓我們異或吧

異或是一種神奇的運算,大部分人把它總結成不進製加法.在生活中 xor運算也很常見。比如,對於乙個問題的回答,是為1,否為0.那麼 a是否是男生 xor b是否是男生 a和b是否能夠成為情侶 好了,現在我們來製造和處理一些複雜的情況。比如我們將給出一顆樹,它很高興自己有n個結點。樹的每條邊上有乙個權值...

P2420 讓我們異或吧

對於異或,就是將之前的求和的 號改為 即可 其他完全一樣 1 include2 using namespace std 3 typedef long long ll 4 const int maxn 200000 10 5 intn,m,r 6 見題意7 intw maxn wt maxn 8 鏈式...