洛谷-P2420 讓我們異或吧

carboxylBase發表於2024-08-05

Abstract

傳送門
很有意思的一道題,需要巧妙的利用異或的結合律。

Idea

不妨取 1 為根節點,然後從 1 出發遍歷整棵樹,將 1 到 n 節點的路徑異或和記錄為 dis[i] ,那麼,顯然有從 i 到 j 的路徑的異或和為 dis[i] ^ dis[j]。

Code

愛來自 namespace

#include <bits/stdc++.h>
int n, m;

namespace graph
{
    const int maxn = 1100000;
    struct Edge
    {
        int next, to, value;
    } edge[maxn];
    int head[maxn];
    int cnt = 0;
    void add(int u, int v, int c)
    {
        cnt++;
        edge[cnt].next = head[u];
        edge[cnt].to = v;
        edge[cnt].value = c;
        head[u] = cnt;
        return;
    }

    int dis[maxn];
    bool vis[maxn];
    void dfs(int pos, int sum)
    {
        dis[pos] = sum;
        vis[pos] = 1;
        for (int i = head[pos]; i; i = edge[i].next)
        {
            if (vis[edge[i].to])
            {
                continue;
            }
            dfs(edge[i].to, sum ^ edge[i].value);
        }
        return;
    }
};

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cin >> n;

    memset(graph::head, 0, sizeof graph::head);
    memset(graph::vis, 0, sizeof graph::vis);
    memset(graph::dis, 0, sizeof graph::dis);
    for (int i = 1; i < n; i++)
    {
        int u, v, c;
        std::cin >> u >> v >> c;
        graph::add(u, v, c);
        graph::add(v, u, c);
    }

    graph::dfs(1, 0);
    std::cin >> m;
    for (int i = 0; i < m; i++)
    {
        int x, y;
        std::cin >> x >> y;
        std::cout << (graph::dis[x] ^ graph::dis[y]) << std::endl;
    }
    return 0;
}

相關文章