2018.07.22 洛谷P3047附近的牛(树形dp)
传送门
给出一棵n" role="presentation" style="position: relative;">nn个点的树,每个点上有Ci" role="presentation" style="position: relative;">CiCi头牛,问每个点k" role="presentation" style="position: relative;">kk步范围内各有多少头牛。
刚看完题惊了这东西不可做啊。
然后就开始想换根dp" role="presentation" style="position: relative;">dpdp,结果没杠出来。
继续读题发现k" role="presentation" style="position: relative;">kk很小啊,才20" role="presentation" style="position: relative;">2020,那这怕不是可以跑一个O(nk)" role="presentation" style="position: relative;">O(nk)O(nk)的算法哦。
然后发现确实可以O(nk)" role="presentation" style="position: relative;">O(nk)O(nk)做出来,方法是这样的。
我们仍然先选一个节点(为了方便我选的就是1" role="presentation" style="position: relative;">11)当根节点,然后用siz[p][k]" role="presentation" style="position: relative;">siz[p][k]siz[p][k]表示出以每个p" role="presentation" style="position: relative;">pp作为根节点的子树中距离p" role="presentation" style="position: relative;">pp不大于k" role="presentation" style="position: relative;">kk的节点的权值和,子树之外的节点都先不管。这个东西是可以先通过儿子的信息先转移出每个p" role="presentation" style="position: relative;">pp作为根节点的子树中距离p" role="presentation" style="position: relative;">pp等于k" role="presentation" style="position: relative;">kk的节点的权值和,然后再跑一边前缀和求出来的,时间复杂度O(nk)" role="presentation" style="position: relative;">O(nk)O(nk),然后对于每一个点u" role="presentation" style="position: relative;">uu,以它作为整个树的根节点时,整棵树的贡献就是沿着u" role="presentation" style="position: relative;">uu到1" role="presentation" style="position: relative;">11的链向上跳,跳到跳不动或者已经跳了k" role="presentation" style="position: relative;">kk步停止,跳的时候用简单的容斥原理统计答案(其实就是累加siz[fa][k]−siz[p][k−1]" role="presentation" style="position: relative;">siz[fa][k]−siz[p][k−1]siz[fa][k]−siz[p][k−1]),时间复杂度仍然是O(nk)" role="presentation" style="position: relative;">O(nk)O(nk)。
代码如下:
#include<bits/stdc++.h>
#define N 100005
using namespace std;
int first[N],n,siz[N][21],cnt=0,dp[N],fa[N],k;
struct Node{int v,next;}e[N<<1];
inline void add(int u,int v){e[++cnt].v=v,e[cnt].next=first[u],first[u]=cnt;}
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
inline void write(int x){
if(x>9)write(x/10);
putchar((x%10)^48);
}
inline void dfs(int p){
for(int i=first[p];i;i=e[i].next){
int v=e[i].v;
if(v==fa[p])continue;
fa[v]=p;
dfs(v);
for(int j=1;j<=k;++j)siz[p][j]+=siz[v][j-1];
}
}
inline int solve(int p){
int ret=siz[p][k],pos=k-1;
while(fa[p]&&pos!=-1){
ret+=siz[fa[p]][pos]-(pos?siz[p][pos-1]:0);
--pos,p=fa[p];
}
return ret;
}
int main(){
n=read(),k=read();
for(int i=1;i<n;++i){
int u=read(),v=read();
add(u,v),add(v,u);
}
for(int i=1;i<=n;++i)siz[i][0]=read();
dfs(1);
for(int i=1;i<=n;++i)for(int j=1;j<=k;++j)siz[i][j]+=siz[i][j-1];
for(int i=1;i<=n;++i)write(solve(i)),puts("");
return 0;
}
2018.07.22 洛谷P3047附近的牛(树形dp)的更多相关文章
- 洛谷P3047 [USACO12FEB]Nearby Cows(树形dp)
P3047 [USACO12FEB]附近的牛Nearby Cows 题目描述 Farmer John has noticed that his cows often move between near ...
- 2018.07.22 洛谷P2986 伟大的奶牛聚集(树形dp)
传送门 给出一棵树,树有边权和点权,若选定一个点作为中心,这棵树的代价是所有点权乘上到根的距离的和.求代价最小. 解法:一道明显的换根dp" role="presentation& ...
- 2018.07.22 洛谷P4316 绿豆蛙的归宿(概率dp)
传送门 简单的递推. 由于是DAG" role="presentation" style="position: relative;">DAGDA ...
- 2018.07.22 洛谷P1967 货车运输(kruskal重构树)
传送门 这道题以前只会树剖和最小生成树+倍增. 而现在学习了一个叫做kruskal" role="presentation" style="position: ...
- 2018.07.22 洛谷P3106 GPS的决斗Dueling GPS's(最短路)
传送门 图论模拟题. 这题直接写3个(可以压成一个)spfa" role="presentation" style="position: relative;&q ...
- 2018.07.09 洛谷P2365 任务安排(线性dp)
P2365 任务安排 题目描述 N个任务排成一个序列在一台机器上等待完成(顺序不得改变),这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间 ...
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- 2018.07.01洛谷P2617 Dynamic Rankings(带修主席树)
P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i ...
- 2018.07.17 洛谷P1368 工艺(最小表示法)
传送门 好的一道最小表示法的裸板,感觉跑起来贼快(写博客时评测速度洛谷第二),这里简单讲讲最小表示法的实现. 首先我们将数组复制一遍接到原数组队尾,然后维护左右指针分别表示两个即将进行比较的字符串的头 ...
随机推荐
- 1.java生成随机不重复10位字符串
package org.changneng.util; import java.util.Random; public class A { public static void main(String ...
- 使用seaborn制图(箱型图)
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # 设置风格, ...
- 使用SendMessage进行进程间通信
Imports System.Runtime.InteropServices Public Class Monitor <DllImport("user32.dll", Ch ...
- Java8函数之旅(四) --四大函数接口
前言 Java8中函数接口有很多,大概有几十个吧,具体究竟是多少我也数不清,所以一开始看的时候感觉一脸懵逼,不过其实根本没那么复杂,毕竟不应该也没必要把一个东西设计的很复杂. 几个单词 在学习 ...
- 【转】oracle 体系结构
前几天面试的时候面试官才问过我Oracle的体系结构,让我在一张白纸上画出来.回头想想当时答得还不错,大部分内容都描述出来了,呵呵,刚才在网上看到一篇讲解ORACLE体系结构的文章,觉得不错,转过来存 ...
- Kotlin语言学习笔记(6)
运算符重载(Operator overloading) 一元运算符 Expression Translated to +a a.unaryPlus() -a a.unaryMinus() !a a.n ...
- python中时间差中seconds和total_seconds
在python中经常会用到计算两个时间差,两个日期类型进行相减可以获取到时间差 经常会使用seconds来获取,其实seconds获取的是时间差的秒数,遗漏了天 seconds是获取时间部分的差值,而 ...
- 02 Tensorflow的安装配置
1 anaconda 64 位,win10 安装 清华大学镜像网络,下载地址:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 选择下载文件 ...
- ORDER BY 子句在视 图、内联函数、派生表、子查询和公用表表达式中无效
SQL语句: select * from (select distinct t2.issue,cashmoney from (select distinct issue from lot_gamepa ...
- php71 gdnz
更新yum库:yum updat yum install epel-release yum install -y gcc gcc-c++ autoconf libjpeg libjpeg-devel ...