再來異或

給你具有nn個結點n1n-1條邊的無向無環連通圖,結點編號1n1 \sim n,每條邊上有一個數作爲他的邊權,定義函數f(i,j)f(i,j)爲連接i,ji,j的簡單路徑的所有邊權的異或值
i=1nj=inf(i,j)\displaystyle \bigoplus_{i=1}^n \bigoplus_{j=i}^n f(i,j)\oplus爲按位異或運算,i=lri\displaystyle \bigoplus_{i=l}^r i表示lrl \sim r所有整數異或後的結果

輸入描述
輸入的第一行爲一個整數TT,代表測試用例的組數
接下來的TT組測試用例按照如下格式給出:
每組數據佔nn行,第一行有11個整數nn,接下來的n1n-1行,每行有33個整數u,v,wu,v,w,分別表示每條邊的起點、終點、權值

輸出描述
對於每組測試數據,在新的一行中輸出答案

數據範圍
1T10001≤T≤1000
1n21051≤n≤2\cdot{10}^5
n2105\sum{n}≤2\cdot{10}^5
1u,vn1≤u,v≤n
0w1060≤w≤10^6

樣例輸入
2
1
2
1 2 3
樣例輸出
0
3

a[x]a[x]爲節點11xx路徑上所有邊權的異或和,s[x]=i=xna[i]s[x]=\bigoplus_{i=x}^n a[i]
因爲f(i,j)=a[i]a[j]f(i,j)=a[i]\oplus a[j],所以j=inf(i,j)={s[j](nj+1)mod  2=0s[j]a[j]else\bigoplus_{j=i}^n f(i,j)=\left\{ \begin{aligned} &s[j] & &{(n-j+1)\mod 2=0}\\ &s[j]\oplus a[j]& &{else} \end{aligned} \right.
ii11nn遍歷一遍求出答案。
複雜度爲O(n)O(n)

#include<bits/stdc++.h>

#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scahf("%c",&a);
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector<int>
#define pii pair<int,int>
#define mii unordered_map<int,int>
#define msi unordered_map<string,int>
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define pr(x) cout<<#x<<": "<<x<<endl
using namespace std;

inline int qr() {
    int f = 0, fu = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-')fu = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        f = (f << 3) + (f << 1) + c - 48;
        c = getchar();
    }
    return f * fu;
}

const int N = 2e5 + 10;
int head[N], ver[N << 1], Next[N << 1], edge[N << 1], tot;
int T, n, a[N], s[N];
bool v[N];

inline void add(int x, int y, int z) {
    ver[++tot] = y;
    Next[tot] = head[x];
    edge[tot] = z;
    head[x] = tot;
}

inline void bfs() {
    repi(i, 1, n)v[i] = false, a[i] = s[i] = 0;
    queue<int> q;
    v[1] = true, q.push(1);
    while (!q.empty()) {
        int x = q.front();
        q.pop();
        reps(x) {
            int y = ver[i], z = edge[i];
            if (v[y])continue;
            v[y] = true, a[y] = a[x] ^ z, q.push(y);
        }
    }
    s[n] = a[n];
    repd(i, n - 1, 1)s[i] = a[i] ^ s[i + 1];
}

int main() {
    T = qr();
    while (T--) {
        n = qr();
        repi(i, 1, n)head[i] = 0;
        repi(i, 1, n - 1) {
            int x = qr(), y = qr(), z = qr();
            add(x, y, z), add(y, x, z);
        }
        bfs();
        int ans = 0;
        repi(i, 1, n) {
            ans ^= s[i];
            if ((n - i + 1) & 1)ans ^= a[i];
        }
        pi(ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章