• 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;
    }
    参考程序
  • 相关阅读:
    .NET System.Web.HttpContext.Current.Request报索引超出数组界限。
    Jq将字符串复制粘贴到剪贴板
    设置VS以管理员身份运行
    http遇到的那些坑,iis上传文件报413错误 asp.net MVC
    百度地图api使用,简单搜索+经纬度定位+自定义消息窗口
    常见的sql server 链接问题------持续更新
    解决电脑不能访问局域网共享,局域网共享中找不到。
    博文图片挂了临时解决办法
    博客声明
    06. redis cluster
  • 原文地址:https://www.cnblogs.com/kcn999/p/10462574.html
Copyright © 2020-2023  润新知