传送门

给出一棵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)的更多相关文章

  1. 洛谷P3047 [USACO12FEB]Nearby Cows(树形dp)

    P3047 [USACO12FEB]附近的牛Nearby Cows 题目描述 Farmer John has noticed that his cows often move between near ...

  2. 2018.07.22 洛谷P2986 伟大的奶牛聚集(树形dp)

    传送门 给出一棵树,树有边权和点权,若选定一个点作为中心,这棵树的代价是所有点权乘上到根的距离的和.求代价最小. 解法:一道明显的换根dp" role="presentation& ...

  3. 2018.07.22 洛谷P4316 绿豆蛙的归宿(概率dp)

    传送门 简单的递推. 由于是DAG" role="presentation" style="position: relative;">DAGDA ...

  4. 2018.07.22 洛谷P1967 货车运输(kruskal重构树)

    传送门 这道题以前只会树剖和最小生成树+倍增. 而现在学习了一个叫做kruskal" role="presentation" style="position: ...

  5. 2018.07.22 洛谷P3106 GPS的决斗Dueling GPS's(最短路)

    传送门 图论模拟题. 这题直接写3个(可以压成一个)spfa" role="presentation" style="position: relative;&q ...

  6. 2018.07.09 洛谷P2365 任务安排(线性dp)

    P2365 任务安排 题目描述 N个任务排成一个序列在一台机器上等待完成(顺序不得改变),这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间 ...

  7. 洛谷 P3177 [HAOI2015]树上染色 树形DP

    洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...

  8. 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 ...

  9. 2018.07.17 洛谷P1368 工艺(最小表示法)

    传送门 好的一道最小表示法的裸板,感觉跑起来贼快(写博客时评测速度洛谷第二),这里简单讲讲最小表示法的实现. 首先我们将数组复制一遍接到原数组队尾,然后维护左右指针分别表示两个即将进行比较的字符串的头 ...

随机推荐

  1. mvc框架路由原理

    到目前为止已经使用过很多php框架,比如:Zendframework,ThinkPHP,YII,Slim.但还未静下心来研究过框架的原理. 今天首先来看一下mvc框架中路由的原理: 所谓路由,就是程序 ...

  2. spring Ioc和DI

    spring的“控制反转”和“依赖注入”,个人看来是一个意思. 传统java程序中,使用一个对象的时候,都需要先new Object()创建一个新对象,才能使用.对象的控制权,在程序手里. 使用spr ...

  3. php解析url并得到url中的参数

    <?php $url = 'http://www.baidu.com/index.php?m=content&c=index&a=lists&catid=6&ar ...

  4. 突破MSDE 的2GB数据限制

    Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\ ...

  5. as3与php交互

    (1)直接读取 php: <? $state="开始接收"; $var1="收到"; echo "state=".$state.&qu ...

  6. vue基础——条件渲染

    一.v-if 1.1.v-if,v-else 在字符串模板中,比如Handlebars,我们得像这样写一个条件块: HTML <!-- Handlebars 模板 --> {{#if ok ...

  7. Haskell语言学习笔记(44)Lens(2)

    自定义 Lens 和 Isos -- Some of the examples in this chapter require a few GHC extensions: -- TemplateHas ...

  8. asp.net cors solution

    I have a simple actionmethod, that returns some json. It runs on ajax.example.com. I need to access ...

  9. JS中创建对象的方法及json

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  10. chrome 调试参数(鼠标事件)

    1.监听鼠标事件: monitorEvents(document.body, 'mouse') 取消监听: unmonitorEvents(document.body) 原文链接: https://b ...