P3047 [USACO12FEB]Nearby Cows G
很经典很好的一个树形dp
很明显dp[i][j]表示距离i在范围j以内的权值和
我们还很容易想到维护一个deep[i][j]数组
表示i的子树中距离i在范围j以内的权值和
这个题难就难在距离i在范围j以内的点可能是在i的上头
这时候转移方程就要考虑率容斥一下
对于(u,v)这条边
dp[u][kk]=dp[v][kk-1]-deep[u][kk-2]+deep[u][kk-1];
这个转移方程真的绝绝子,以后很多题目都可以联想到这个方法
还有很多细节在下面代码里面,要想完整写出来确实很有难度
点击查看代码
#include
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=1e5+5;
int val[maxn];
vectorQ[maxn];
int n,k;
int d[maxn][25],dp[maxn][25];
void dfs(int u,int fa,int kk){
d[u][kk]+=val[u];//首先要加上他本身
for(int i=0;i=2)
dp[u][kk]=dp[fa][kk-1]-d[u][kk-2]+d[u][kk];
else
dp[u][kk]=dp[fa][kk-1]+d[u][kk];//在kk<2的情况下,就压根不需要容斥了,dp[fa][kk-1]就没有包括d[u][kk-2]
for(int i=0;i