异或前缀和+DFS hdu5416 CRB and Tree
来源:互联网 发布:java从键盘赋值 编辑:程序博客网 时间:2024/04/30 04:31
传送门:点击打开链接
题意:给你一棵树,然后Q个问题,每个问题询问有存在多少个f(u,v)等于s其中u<=v,f(u,v)表示节点u到节点v所有边的权值异或和
思路:这道题我觉得出的非常好,运用了位异或的一些妙用。f(u,v)=f(1,u)^f(1,v),因为假设u,v的lca是p,那么1~p这些节点都是公用的,这部分被异或了两次,就抵消了
然后对于Q次问题,假设某一次问题是s,则有s=f(u,v)=f(1,u)^f(1,v)。那么有f(1,v)=s^f(1,u),也就是说,如果我们DFS到节点u,算出了f(1,v),那么对于某一个s,我们就需要算出f(1,v)等于多少,然后再通过cnt数组知道f(1,v)有多少个,把这个值累加到s这个查询的答案中去,就这样DFS遍历完整个树,答案就离线处理完了。复杂度O(Q*N)
trick:当出现下面这种数据的时候
1101 2 02 3 03 4 04 5 05 6 06 7 07 8 08 9 010
可以看出来,答案会等于n(n-1)/2,因为n最大是1e5,所以结果可能会爆int,要用long long保存
#include<map>#include<set>#include<cmath>#include<stack>#include<queue>#include<cstdio>#include<string>#include<vector>#include<cstring>#include<iostream>#include<algorithm>#include<functional>#define FIN freopen("input.txt","r",stdin)#define FOUT freopen("output.txt","w+",stdout)using namespace std;typedef long long LL;typedef pair<int, int> PII;const int MX = 2e5 + 5;const int INF = 0x3f3f3f3f;int Head[MX], Next[MX], rear;struct Edge { int u, v, cost;} E[MX];void edge_init() { rear = 0; memset(Head, -1, sizeof(Head));}void edge_add(int u, int v, int cost) { E[rear].u = u; E[rear].v = v; E[rear].cost = cost; Next[rear] = Head[u]; Head[u] = rear++;}LL ans[MX];int cnt[MX], Q[MX], Qt;void DFS(int u, int f, int s) { cnt[s]++; for(int j = 1; j <= Qt; j++) { ans[j] += cnt[s ^ Q[j]]; } for(int i = Head[u]; ~i; i = Next[i]) { int v = E[i].v; if(f == v) continue; DFS(v, u, s ^ E[i].cost); }}int main() { int T, n;//FIN; scanf("%d", &T); while(T--) { edge_init(); memset(cnt, 0, sizeof(cnt)); memset(ans, 0, sizeof(ans)); scanf("%d", &n); for(int i = 1; i <= n - 1; i++) { int u, v, cost; scanf("%d%d%d", &u, &v, &cost); edge_add(u, v, cost); edge_add(v, u, cost); } scanf("%d", &Qt); for(int i = 1; i <= Qt; i++) { scanf("%d", &Q[i]); } DFS(1, -1, 0); for(int i = 1; i <= Qt; i++) { printf("%I64d\n", ans[i]); } } return 0;}
1 0
- 异或前缀和+DFS hdu5416 CRB and Tree
- HDU 5416 CRB and Tree 异或前缀和
- hdu 5416 CRB and Tree(dfs+前缀和)
- hdu5416 CRB and Tree(树形DP)
- hdu5416 CRB and Tree(树型dp)
- HDU 5416 CRB and Tree(dfs 异或逆运算)
- 前缀和,LCA(CRB and Tree,HDU 5416)
- HDU 5416 CRB and Tree dfs
- HDU 5416 CRB and Tree (DFS)
- hdu 5416 CRB and Tree (DFS)
- HDOJ 5416 CRB and Tree DFS
- HDU 5416 CRB and Tree(dfs)
- hdu 5416 CRB and Tree(异或运算)
- hdu 5416 CRB and Tree(异或,思路题)
- hdu 5416 CRB and Tree 离线处理树xor前缀
- hdu5416 树形dp 树上路径异或和
- hdu 5416 CRB and Tree 求树上路径异或结果为s的有多少
- 5416 CRB and Tree
- iOS中设置导航栏标题的字体颜色和大小
- oc中的文件
- caffe的输入
- android之interpolator的用法详解
- 小白的Spring学习之路
- 异或前缀和+DFS hdu5416 CRB and Tree
- 主成分分析Matlab实现
- 大整数相乘(aijud)
- 打电话几种形式
- HDOJ1087 Super Jumping! Jumping! Jumping!
- Invert Binary Tree
- tcpdump抓包二进制tcp协议详细分析
- 0001.scala环境搭建
- iOS第三方开源库的吐槽和备忘