• 异或的路径 新疆省赛 (按位亦或)


    链接:https://ac.nowcoder.com/acm/contest/911/J
    来源:牛客网
     

    异或的路径

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 32768K,其他语言65536K
    64bit IO Format: %lld

    题目描述

    给一棵 n 个点的树,1 号节点为根,边有边权,令 f(u,v) 表示 u 节点到 v 节点,路径上边权异或值。求 ∑ni=1∑nj=1f(i,j)∑i=1n∑j=1nf(i,j),结果对 1000000007 取模。

    输入描述:

    第一行一个整数 n(n≤100000)n(n≤100000),接下来 n-1 行,第 i 行输入两个整数,p[i](p[i] < i), v[i](100000>=v[i]>=1)   (分别表示 i+1号节点的父亲,以及 i+1 与 p[i] 相连的边的权值。

    输出描述:

    输出一个整数表示答案。

    示例1

    输入

    复制

    3
    1 1
    1 1

    输出

    复制

    4

    示例2

    输入

    复制

    5
    1 1
    2 2
    3 3
    4 4

    输出

    复制

    60

    备注:

    样例 1,f(1,2)=f(2,1)=f(1,3)=f(3,1)=1,f(1,1)=f(2,2)=f(3,3)=f(2,3)=f(3,2)=0、

    在一棵树上任意两点之间的路径间的亦或和相加

    我们看一眼数据范围就知道是必不可可能进行暴力求解的

    首先将所有点到根节点的异或和求出

    那么如何求解两个点之间路径的亦或和呢

    我们根据亦或的性质可推出只要将两个要根节点的亦或和进行亦或 

    那么重合的路径就会被 消去 所以我们可以发现异或和

    即使是这样要全部求解复杂度依旧是n*n

    不能直接求解 那么我们就看每个点对答案的贡献

    如果我们按位看就可以知道 如果一个点的一位是0那么只有另一个点是1才对但有贡献

    推出每一位各个点的贡献值相加就可以得到答案

    #include<bits/stdc++.h>
    using namespace std;
    const long long mod=1000000007;
    vector<pair<int,int> > G[100007];
    long long w[100007];
    void dfs(int u)
    {
        for(auto v : G[u])
        {
            w[v.first]=v.second^w[u];
            dfs(v.first);
        }
        return ;
    }
    int main()
    {
        long long n;
        scanf("%lld",&n);
        for(int i=2;i<=n;i++)
        {
            int tmp1,tmp2;
            cin>>tmp1>>tmp2;
            G[tmp1].push_back(make_pair(i,tmp2));
        }
        dfs(1);
        long long ans=0;
        for(int i=0;i<=20;i++)
        {
            long long cnt=0;
            long long tmp;
            for(int j=1;j<=n;j++)
            {
                if((w[j]>>i)&1) cnt++;
            }
            tmp=1<<i;
            ans=(ans+(cnt*(n-cnt)%mod)*(tmp)%mod)%mod;
            //out<<i<<" "<<cnt<<" "<<tmp<<" "<<ans<<endl;
        }
    //    for(int j=1;j<=n;j++)
    //    {
    //        cout<<w[j]<<endl;
    //    }
        ans=(ans<<1)%mod;
        cout<<ans<<endl;
    }
    
  • 相关阅读:
    Android 沉浸式状态栏的三种实现方式
    大数据量高并发访问的数据库优化方法(一)
    Spring Boot实战:集成Swagger2
    JVM学习之GC常用算法
    java并发面试题
    Java面试处理高并发
    jedis操作redis的几种常见方式总结
    彻底理解数据库事物
    Java集合——HashMap、HashTable以及ConCurrentHashMap异同比较
    HashMap的工作原理
  • 原文地址:https://www.cnblogs.com/caowenbo/p/11852248.html
Copyright © 2020-2023  润新知