zoukankan      html  css  js  c++  java
  • 牛客网 272B Xor Path(树上操作)

    题目链接:Xor Path

    题意:每个顶点的点权为Ai,任意两点路径上点权异或和为Path(i,j),求所有Path(i,j)和。

    题解:考虑每个顶点被用到的次数,分以下三种情况:

    1.本身和其他顶点:n-1

    2.该顶点上面的顶点(k)和下面的顶点(m)通过该点进行连接:k*m

    3.该顶底下面的顶点通过该点进行连接(上面顶点不用的原因是:从上层层下来,已经记录过。):任意两个子树个数相乘之和。

    第三种情况直接算会超时,我们需要优化一下,考虑下如果子树个数为偶数相当于没有贡献,所以只要考虑子树个数为奇数的即可,最后判断下C(cnt,2)是否为奇数,奇数的话贡献+1。

     1 #include <cstdio>
     2 #include <vector>
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 const int N=5e5+10;
     7 int a[N],ans=0;
     8 ll sz[N],n;
     9 vector <int> E[N];
    10 
    11 void dfs(int u,int fa){
    12     sz[u]=1;
    13     ll sum=0,cnt=0;
    14     for(int i=0;i<E[u].size();i++){
    15         int v=E[u][i];
    16         if(v!=fa){
    17             dfs(v,u);
    18             sz[u]+=sz[v];
    19             if(sz[v]%2==1) cnt++;
    20         }
    21     }
    22     //第三种情况
    23     if((cnt*(cnt-1)/2)%2) sum++;
    24     //n-1为第一种情况,(sz[u]-1)*(n-sz[u])为第二种情况.
    25     sum=(sum+(n-1)+(sz[u]-1)*(n-sz[u])%2)%2;
    26     if(sum%2==1) ans^=a[u];
    27 }
    28 
    29 int main(){
    30     scanf("%d",&n);
    31     for(int i=1;i<n;i++){
    32         int u,v;
    33         scanf("%d%d",&u,&v);
    34         E[u].push_back(v);
    35         E[v].push_back(u);
    36     }
    37     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    38     dfs(1,0);
    39     printf("%d
    ",ans);
    40     return 0;
    41 }
    View Code
  • 相关阅读:
    解决ubuntu中firefox浏览器总是提示找不到server的问题
    Android学习笔记(14):相对布局RelativeLayout
    浅析java(多方面解读)
    做自己
    SGU 261. Discrete Roots (N次剩余)
    hdu1115 Lifting the Stone(几何,求多边形重心模板题)
    Android编码规范
    hdu 3790 最短路径问题
    怎样在gluster的源代码中加入自己的xlator
    处理空列表
  • 原文地址:https://www.cnblogs.com/pavtlly/p/10046959.html
Copyright © 2011-2022 走看看