hdu 5416 CRB and Tree(dfs+前缀和)
2015-08-20 20:25
197 查看
题意:
在一棵树上有n个点,n-1条边,每条边都有一个权值。令f(u,v)f(u,v)等于u到v这条路径上的前缀和。
现在给你Q次询问(Q<=10)(Q<=10)
询问f(u,v)=sf(u,v)=s的路径有多少条。
解析:
由于Q比较小可以直接利用O(n)复杂度的算法来做。先用sum[u]保存下,从根节点到u的异或和是多少。
用一个hash map来保存,sum[u]出现了多少次。
每次就查询hash map中ss ^ sum[u]sum[u]出现了多少次。
查询的总和除以2就是最终结果。
注意:
如果s=0s=0时,f(u,u)f(u,u)也满足条件,所以还要再加上n。mymy codecode
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #define pb push_back using namespace std; typedef long long ll; const int maxn = (int)2e5 + 10; struct Edge { int u, v, val; Edge() {} Edge(int u, int v, int val) : u(u), v(v), val(val) {} }; int mp[maxn], sum[maxn]; vector<Edge> G[maxn]; int n, q; void init() { memset(mp, 0, sizeof(mp)); for(int i = 1; i <= n; i++) { G[i].clear(); } } void addEdge(int u, int v, int val) { G[u].pb(Edge(u, v, val)); } void dfs(int u, int pre, int val) { sum[u] = val; for(int i = 0; i < G[u].size(); i++) { int v = G[u][i].v; if(pre == v) continue; dfs(v, u, val^G[u][i].val); } } ll cal(int s) { ll ret = 0; for(int i = 1; i <= n; i++) { ret += mp[s^sum[i]]; } if(s == 0) ret += n; return ret / 2; } int main() { int T; scanf("%d", &T); int u, v, val, s; while(T--) { scanf("%d", &n); init(); for(int i = 1; i < n; i++) { scanf("%d%d%d", &u, &v, &val); addEdge(u, v, val); addEdge(v, u, val); } dfs(1, -1, 0); for(int i = 1; i <= n; i++) { mp[sum[i]]++; } scanf("%d", &q); while(q--) { scanf("%d", &s); printf("%lld\n", cal(s)); } } return 0; }
相关文章推荐
- hdu 5410 CRB and His Birthday 2015多校联合训练赛#10 dp 动态规划
- 快速地从Redhat系转Ubuntu系
- Inviting Friends(二分+背包)
- 详解。。。设计模式3——值对象。。。studying
- 【软件工程】机房收费系统之图形回顾
- Inviting Friends(二分+背包)
- C语言动态走迷宫
- 一个人的旅行(http://acm.hdu.edu.cn/showproblem.php?pid=2066)SPFA||dijkstra
- Cable master
- NEFU 117-素数个数的位数(素数定理)
- [CQOI2007]三角形tri 解题报告
- 用C语言求N!
- 加法计算器
- ppc_85xx-gcc -shared -fPIC liberr.c -o liberr.so
- 详解。。。设计模式2——工厂。。。studying
- 2015.8.20 多校#10 1009 CRB and String
- 结构体指针 宏 预编译
- UVA表达式树的后序遍历和层次遍历和建树
- hdu 5414 CRB and String 2015多校联合训练赛#10 贪心
- 粗略。。类设计的基本经验2之笔记