题干:

给定一棵n个点的树,每个点有权值。定义表示  到  的最短路径上,所有点的点权异或和。

对于,求所有的异或和。

输入描述:

 

第一行一个整数n。

接下来n-1行,每行2个整数u,v,表示u,v之间有一条边。

第n+1行有n个整数,表示每个点的权值

输出描述:

输出一个整数,表示所有的异或和,其中。

示例1

输入

复制

4
1 2
1 3
1 4
1 2 3 4

输出

复制

5

说明

 

再将这6个数异或起来就可以得到答案5了。

备注:

题目大意:

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

解题报告:

比较套路的一道题,。,算一下每个节点的贡献就行了。牵扯异或了所以肯定要看是否会有重复操作(因为对这个点进行两次异或就会使得原结果不变)

一个题解:

考虑每个顶点,有三种情况被用到

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

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

3.该顶底下面的顶点通过该点进行连接(上面顶点不用的原因是:从上层层下来,已经记录过。):任意两个子树个数相乘之和。(比较难想,,注意一下使用一个技巧: 只有 奇数*奇数 才=奇数,,就方便思考了)

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

AC代码:(500-700ms第一次交TLE了、、)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 7e5 + 5;
vector<int> vv[MAX];
ll dp[MAX],ans;
ll a[MAX];
int n;
ll dfs(int cur,int rt) {int up = (int)vv[cur].size();ll tmp,cnt=0,sum=0;for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == rt) continue;tmp = dfs(v,cur);dp[cur] += tmp; if(tmp%2==1) cnt++;}if((cnt*(cnt-1)/2)%2) sum++;sum+=n-1;sum+= (dp[cur]-1) * (n - dp[cur]);
//  sum=(sum+(n-1)+(dp[cur]-1)*(n-dp[cur])%2)%2; 用这一行也可以AC、、、if(sum%2==1) ans ^= a[cur];return dp[cur];
}
int main()
{cin>>n;for(int i = 1,u,v; i<=n-1; i++) {scanf("%d%d",&u,&v);vv[u].pb(v);vv[v].pb(u);} for(int i = 1; i<=n; i++) scanf("%lld",a+i),dp[i]=1;dfs(1,-1);printf("%lld\n",ans);return 0 ;}

总结:

这题刚开始没有初始化dp[i]=1,,倒置用注释和不用注释的结果不一样,我当时还在想为什么会不一样,,因为在哪取模应该都一样啊,,后来发现是因为dp[cur]-1 那里就变成-1了,,所以先取模和后驱魔结果才会不一样,,虽然都不是正确结果但是当时句式想研究一下为什么两种方式会得出不一样的结果,现在知道了,,并且dp[i]显然要赋值为1啊。。

再附一个快的飞起的短代码:(177ms)

#include<bits/stdc++.h>
#define ll long long
#define N 500010
using namespace std;
template <typename T> void read(T &x){x=0;char c=getchar();int fh=1;while (!isdigit(c)){if (c=='-')fh=-1;c=getchar();}while (isdigit(c))x=x*10+c-'0',c=getchar();x*=fh;
}
struct Info{int nu,ne;}a[N*2];
int b[N],num,x,y,v[N],n;
ll si[N],ansn;
void jb(int x,int y){a[++num].nu=y;a[num].ne=b[x];b[x]=num;}
void dfs(int x,int fa){ll sum=0;si[x]=1;for (int y=b[x];y;y=a[y].ne){if (a[y].nu!=fa){dfs(a[y].nu,x);sum=sum+si[a[y].nu]*si[x];si[x]+=si[a[y].nu];}}sum=sum+si[x]*(n-si[x]);if (sum%2==1)ansn^=v[x];
}
int main(){read(n);for (int i=1;i<n;i++){read(x);read(y);jb(x,y);jb(y,x);}for (int i=1;i<=n;i++){read(v[i]);}dfs(1,0);cout<<ansn<<endl;return 0;
}

std:

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=1e6+5;int n,Ans,Enum,H[N],nxt[N<<1],to[N<<1],A[N],sz[N];inline int read()
{int now=0;register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-'0',c=gc());return now;
}
inline void AE(int u,int v)
{to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void DFS(int x,int fa)
{sz[x]=1;for(int i=H[x],v; i; i=nxt[i])if((v=to[i])!=fa) DFS(v,x), sz[x]+=sz[v];LL tmp=n-sz[x];//不经过x的子树的路径for(int s=n-sz[x]+1,i=H[x],v; i; i=nxt[i])if((v=to[i])!=fa) tmp+=1ll*s*sz[v], s+=sz[v];//经过v这个孩子节点的 那一串子树的。再累加。(话说,,为啥不会爆longlong呢?)if(tmp&1) Ans^=A[x];
}
int main()
{n=read();for(int i=1; i<n; ++i) AE(read(),read());for(int i=1; i<=n; ++i) A[i]=read();DFS(1,1), printf("%d\n",Ans);fclose(stdin), fclose(stdout);return 0;
}

【牛客 - 272B】Xor Path(树上操作,路径异或值)相关推荐

  1. 牛客网 短最优升级路径 【Dijkstra算法】+【路径记录】

    链接:https://www.nowcoder.com/questionTerminal/a7052c5bd8634edb9ccee711a5c1ea54 来源:牛客网 短最优升级路径 题目描述:游戏 ...

  2. 牛客题霸 [矩阵的最小路径和] C++题解/答案

    牛客题霸 [矩阵的最小路径和] C++题解/答案. 题目描述 给定一个 n * m 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的 ...

  3. 牛客网算法题 (一) 办公室路径条数解法 Shopee的办公室(二)

    办公室路径走法 题目描述 shopee的办公室非常大,小虾同学的位置坐落在右上角,而大门却在左下角,可以把所有位置抽象为一个网格(门口的坐标为0,0),小虾同学很聪明,每次只向上,或者向右走,因为这样 ...

  4. 牛客 - 17968 - xor序列 - 线性基

    https://ac.nowcoder.com/acm/problem/17968 下面是错误的做法,因为题目要求必须使用x,而y在check的时候不一定用到等价于x的线性基来构成. 正确的做法是直接 ...

  5. 2021牛客第一场H.Hash Function—FFT求差值的卷

    https://ac.nowcoder.com/acm/contest/11166/H 官方题解. 比赛时,我们都是用暴力写的,数据太弱了,今天突然想起来,用fft写了一下. 主要使用fft求差值的卷 ...

  6. 2019暑期训练——牛客第七场 C. Governing sand(权值线段树)

    Governing sand 链接: https://ac.nowcoder.com/acm/contest/887/C 题意: 给n种树,其中每一种树都有高度h,每砍掉一棵树所需要的代价c,这种树的 ...

  7. 牛客练习赛26 D xor序列 (线性基)

    链接:https://ac.nowcoder.com/acm/contest/180/D 来源:牛客网 xor序列 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他 ...

  8. 洛谷or牛客数据结构+算法

    栈思想:先进后出 tips:栈里能放下标就放下标 (牛客)小c的计事本(直接用stack可以简化代码,且不会被自己绕晕,当时没意识到) (牛客)吐泡泡(没意识到用栈),(牛客)好串 1.后缀表达式(栈 ...

  9. 牛客题霸题目及题解汇总

    牛客题霸 单链表的选择排序 C++题解/答案 牛客题霸 最少素数拆分 C++题解/答案 牛客题霸 两数之和 C++题解/答案 牛客题霸 反转链表 C++题解/答案 牛客题霸 二分查找 C++题解/答案 ...

最新文章

  1. 潜在狄利克雷分配(LDA,Latent Dirichlet Allocation)模型(一)
  2. c语言密钥短语密码得到代替字母表,c语言程序设计竞赛题及其答案
  3. 建立索引要考虑的因素
  4. QQ空间Python爬虫v2.0--点赞数据分析
  5. [转]Ubuntu 常用快捷键10个
  6. POJ 2240 Arbitrage(SPFA判正环)
  7. ElasticSearch的搜索推荐(typeahead)
  8. android bitmap转image
  9. C++里中文转拼音那点事
  10. Win10 桌面图标出现空文件夹的删除及桌面图标排列问题
  11. SCCM 2016安装部署
  12. html中隐藏溢出怎么写,CSS溢出文字隐藏
  13. 第2篇,到底什么是互联网思维?
  14. 华硕的电脑装linux系统安装教程,华硕笔记本电脑一键重装系统详细教程
  15. 神经网络的基本骨架-nn.Moudle的使用
  16. mysql 家谱树查询_GitHub - chenwei/FamilyTreeView: 家谱树绘制Demo
  17. android跨应用调用方法是,Android如何实现不同应用之间的调用
  18. vs2017开发ActiveX(主讲OCX)(七)、方法
  19. html+css实现多层表格嵌套
  20. 我的世界网易版java材质包下载_我的世界网易版服务器怎么加材质包

热门文章

  1. [Leetcode][第309题][JAVA][最佳买卖股票时机含冷冻期][动态规划][压缩空间]
  2. [剑指offer][JAVA]面试题第[26]题[树的子结构][递归]
  3. android glide 版本,Android Studio 第六十七期 - Android Glide3.7.0和3.8.0用法
  4. python stringstrip方法详解_Python 基础知识全篇-字符串(Strings)
  5. 系统云服务器,系统云服务器
  6. 不用电脑怎么设置苹果铃声_苹果手机怎么设置铃声?完整教程分享
  7. Java设计模式笔记(6)观察者模式
  8. python的web可视化_Python的Web可视化框架Dash(8)---核心组件
  9. python解释器的提示符是shell嘛_python解释器怎么运行
  10. tidb vs mysql_一个长耗时SQL在TiDB和Mysql上的耗时测试