• GHOJ 905 游历汉中


    题目描述

      因为有你的帮忙,pear传教过程中的询问不需要bx2k来算了。趁这个时间,bx2k开始游历汉中。

      汉中人民热爱树,所以他们的城市也是树形的。bx2k在汉中有很多喜欢的地点对(u,v),于是他用步伐测量出了每个地点对的距离。做完这个任务后,他回去告诉了pear。pear表示仅仅是距离太弱了,他觉得bx2k应该把城市对之间所有道路的异或和(如果你不知道异或和是啥,请看提示)求出来。bx2k已经不想再走了,于是他把汉中的地图告诉你,让你来帮他完成任务。

    输入输出格式

    输入格式

      第一行包含两个整数n,m,代表汉中有n个地点,bx2k有m个喜欢的地点对。

      接下来n-1行,每行包含3个整数u,v,k,代表地点u到地点v之间有一条长度为k的双向道路。

      接下来m行,每行包含两个整数u,v,代表bx2k喜欢的地点对。

    输出格式

      m行,每i行代表第i个地点对之间所有道路的异或和。

    输入输出样例

    输入样例

    5 5

    2 1 25431

    3 1 25971

    4 3 11525

    5 4 9170

    4 3

    5 3

    2 1

    3 2

    4 1

    输出样例

    11525

    3799

    25431

    1572

    18550

    说明

    数据规模

      对于30%的数据,n,m≤10;

      对于70%的数据,n,m≤10^3

      对于90%的数据,除1号点外,每个点i均与floor(i/2)有边。

      对于100%的数据,n,m,k≤10^5;u,v≤n。

    题解

      这道题看起来要求lca,但实际上点u和点v的异或和为根到点u和根到点v的异或和(因为点u和点v的所有公共祖先会异或2次,即它们的异或和为0)

      具体参考下面的代码。

    #include <iostream>
    #include <cstdio>
    
    #define MAX_N 100000
    #define MAX_M 100000
    
    using namespace std;
    
    int n, m;
    
    struct Edge
    {
        int next;
        int to;
        int val;
    };
    Edge a[(MAX_N << 1) + 5];
    int h[MAX_N + 5];
    // edge
    
    const int root = 1;
    struct Tree
    {
        int parent;
        int sum;
    };
    Tree t[MAX_N + 5];
    // tree
    
    inline void Make_Edge(int idx, int u, int v, int k)
    {
        a[idx].to = v;
        a[idx].val = k;
        a[idx].next = h[u];
        h[u] = idx;
        return;
    }
    
    void Build_Tree()
    {
        int x;
        int st[MAX_N + 5], lt = 1, rt = 1;
        st[lt] = root;
        while(lt <= rt)
        {
            x = st[lt++];
            for(register int i = h[x]; i; i = a[i].next)
            {
                if(a[i].to != t[x].parent)
                {
                    t[a[i].to].parent = x;
                    t[a[i].to].sum ^= t[x].sum ^ a[i].val;
                    st[++rt] = a[i].to;
                }
            }
        }
        return;
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        int u, v, k;
        for(register int i = 1; i < n; ++i)
        {
            scanf("%d%d%d", &u, &v, &k);
            Make_Edge(i, u, v, k);
            Make_Edge(i + n, v, u, k);
        }
        Build_Tree();
        for(register int i = 1; i <= m; ++i)
        {
            scanf("%d%d", &u, &v);
            printf("%d
    ", t[u].sum ^ t[v].sum);
        }
        return 0;
    }
    参考程序
  • 相关阅读:
    1074. Reversing Linked List (25)
    1056. Mice and Rice (25)
    1051. Pop Sequence (25)
    1001. A+B Format (20)
    1048. 数字加密(20)
    1073. Scientific Notation (20)
    1061. Dating (20)
    1009. 说反话 (20)
    MyBatis学习总结(8)——Mybatis3.x与Spring4.x整合
    MyBatis学习总结(8)——Mybatis3.x与Spring4.x整合
  • 原文地址:https://www.cnblogs.com/kcn999/p/10462574.html
Copyright © 2020-2023  润新知