树DP 小奇的仓库(warehouse)
来源:互联网 发布:php二次开发用什么 编辑:程序博客网 时间:2024/04/27 20:27
问题 C: 小奇的仓库(warehouse)
时间限制: 1 Sec 内存限制: 256 MB
提交: 121 解决: 30
[提交][状态]
题目描述
【题目背景】
小奇采的矿实在太多了,它准备在喵星系建个矿石仓库。令它无语的是,喵星系的货运飞船引擎还停留在上元时代!
【问题描述】
喵星系有n个星球,星球以及星球间的航线形成一棵树。
从星球a到星球b要花费[dis(a,b) Xor M]秒。(dis(a,b)表示ab间的航线长度,Xor为位运算中的异或)
为了给仓库选址,小奇想知道,星球i(1<=i<=n)到其它所有星球花费的时间之和。
【输入格式】
第一行包含两个正整数n,M。
接下来n-1行,每行3个正整数a,b,c,表示a,b之间的航线长度为c。
【输出格式】
n行,每行一个整数,表示星球i到其它所有星球花费的时间之和。
【样例输入】
4 0
1 2 1
1 3 2
1 4 3
【样例输出】
6
8
10
12
【数据范围】略
保证答案不超过2*10^9
但看着数据范围,只能是O(N)效率。
首先想想m=0的情况:完全不用^,那么两遍dfs就解决问题了。主题思路就是一边算儿子传到父亲的,一遍算父亲传到儿子的。
再考虑m=1的情况,只要知道有多少个点到自己的距离是奇数,多少是偶数就行。也就是两遍dfs时多传个参,再根据边权是奇是偶讨论一下就好了。
我们延续上面的思路,m<=15,也就是说只会改变后四位的值,同理,我们记录后四位的值就好了,传递时,只要把后四位的值+边权,再取后四位即可。
到头来就是两遍dfs。
#include <cstdlib>#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;#define N 100006 int read(){ int sum=0,f=1;char x=getchar(); while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();} while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();} return sum*f;}struct road{int v,next,l;}lu[N*2];int n,m,e,adj[N],f[N],g[N],sz[N],up[N][17];void add(int u,int v,int l){lu[++e]=(road){v,adj[u],l};adj[u]=e;}void dfs1(int x,int fa){ sz[x]=1; for(int i=adj[x];i;i=lu[i].next) { int to=lu[i].v,l=lu[i].l;if(to==fa)continue; dfs1(to,x); g[x]+=g[to]+lu[i].l*sz[to];sz[x]+=sz[to]; for(int j=0;j<16;j++) { int k=j+l;k-=k>>4<<4; up[x][k]+=up[to][j]; } up[x][l-(l>>4<<4)]++; }}void dfs2(int x,int fa,int cnt){ g[x]+=f[x];int sum=g[x],s=cnt+sz[x]; int d[20]; for(int i=adj[x];i;i=lu[i].next) { int to=lu[i].v,l=lu[i].l;if(to==fa)continue; f[to]=sum-g[to]+lu[i].l*(s-sz[to]*2); for(int i=0;i<16;i++)d[i]=up[x][i]; for(int j=0;j<16;j++) { int k=j+l;k-=k>>4<<4; d[k]-=up[to][j]; } d[l-(l>>4<<4)]--; for(int j=0;j<16;j++) { int k=j+l;k-=k>>4<<4; up[to][k]+=d[j]; } up[to][l-(l>>4<<4)]++; dfs2(to,x,s-sz[to]); }}int main(){ n=read();m=read(); int x,y,z; for(int i=1;i<n;i++) { x=read();y=read();z=read(); add(x,y,z);add(y,x,z); } dfs1(1,0); dfs2(1,0,0); /*for(int i=1;i<=n;i++) { for(int j=0;j<16;j++) cout<<up[i][j]<<" "; cout<<endl; }*/ for(int i=1;i<=n;i++) { for(int j=0;j<16;j++) { int k=j^m; g[i]+=(k-j)*up[i][j]; } printf("%d\n",g[i]); }}
阅读全文
0 0
- 树DP 小奇的仓库(warehouse)
- 小奇的矩阵 DP
- 坐标DP 小奇的矩阵(matrix)
- BZOJ4550 小奇的博弈 【Nimk游戏 + dp + 组合数】
- 【BZOJ4548】小奇的糖果
- BZOJ4548 小奇的糖果
- 小奇的数列 Seq
- [bzoj4550] 小奇的博弈
- 【BZOJ4547】小奇的集合
- [JZOJ5229] 小奇的糖果
- 【BZOJ4548】小奇的糖果
- bzoj 2281: [Sdoi2011]黑白棋 && bzoj 4550: 小奇的博弈(Nimk博弈+DP)
- bzoj 4547: Hdu5171 小奇的集合
- BZOJ4547 Hdu5171 小奇的集合
- 【bzoj4547】【小奇的集合】【矩阵乘法】
- BZOJ 4548 小奇的糖果
- 【GDOI2018模拟7.14】小奇的糖果
- bzoj 4548: 小奇的糖果(线段树+树状数组)
- MySQL如何传输二进制日志(二)
- 获取url的部分参数
- C#陷阱和容易搞错的知识点总结
- 静态链表的实现
- leetcode 5. Longest Palindromic Substring
- 树DP 小奇的仓库(warehouse)
- Codeforces330B. Road Construction 贪心水题
- 哈希函数--字符串哈希--hdu1800 Flying to the Mars
- Static修饰符 , 成员变量 , 局部变量
- *L 和 *&L的意义和区别以及头结点问题
- 540. Single Element in a Sorted Array Difficulty:Medium
- Android Dalvik VM内存优化之内存查看篇。
- ros机器人直行1米再旋转180度,最终回到起点
- Xshell连接虚拟机centos