首页 > 其他分享 >CF771C Bear and Tree Jumps

CF771C Bear and Tree Jumps

时间:2024-04-25 13:35:37浏览次数:19  
标签:head le idx int siz Jumps CF771C Tree edges

题目大意:

给定一棵有 \(n\) 个节点的树,要你统计 \(\sum _{1 \le x \le y \le n} {dist(x,y)/k}\) (\(dist(x,y)\) 表示 \(x\) 到 \(y\) 的距离)

\(n \le 2 \times 10^5,k \le 5\)

解法:

一道换根 \(dp\) 套路题。

首先看到树上统计问题,考虑树形 \(dp\),那么我们设 \(g(u)\) 为以 \(u\) 为根节点时子树的答案。

此时我们发现,这个状态定义十分的不可做,无法计算贡献和转移。

观察到 \(k\) 的值域很小,所以多添加一维距离 \(i\)。具体的状态定义就变为了 \(g(u,i)\) 表示在以 \(u\) 为根的子树,距离为 \(i\) 的节点的产生的贡献和。

这个时候就很好转移了,直接有:

  • \(g(u,0)=\sum g(v,k-1)+siz[v]\)

  • \(g(u,i)=\sum g(v,i-1)|i>0\)

但是这统计的只是子树中的贡献,没有统计子树外的,那么自然而然的就想到了换根 \(dp\)

设 \(f(u,i)\) 为整棵树中,与 \(u\) 距离为 \(i\) 的节点产生的贡献和。

显然的可以推出公式了。

code:

#include<bits/stdc++.h>
#define int long long 
using namespace std;

const int N=2e5+10;
int n,k,g[N][6],f[N][6],siz[N],ans,val[6];
struct edge{
	int v,next;
}edges[N*2];
int head[N],idx;
void add_edge(int u,int v){
	idx++;
	edges[idx].v=v;
	edges[idx].next=head[u];
	head[u]=idx;
	return;
}
void dfs1(int u,int fa){
	siz[u]=1;
	for(int i=head[u];i;i=edges[i].next){
		int v=edges[i].v;
		if(v==fa)continue;
		dfs1(v,u);
		g[u][0]+=siz[v]+g[v][k-1];
		for(int j=1;j<k;j++)g[u][j]+=g[v][j-1];
		siz[u]+=siz[v];
	}
	return;
}
void dfs2(int u,int fa){
	if(u==1){for(int i=0;i<=k;i++)f[u][i]=g[u][i];}
	else{
		val[0]=f[fa][0]-g[u][k-1]-siz[u];
		for(int i=1;i<k;i++)val[i]=f[fa][i]-g[u][i-1];
		f[u][0]=g[u][0]+val[k-1]+n-siz[u];
		for(int i=1;i<k;i++)f[u][i]=g[u][i]+val[i-1];
	}
	for(int i=head[u];i;i=edges[i].next){
		int v=edges[i].v;
		if(v!=fa)dfs2(v,u);
	}
	return;
}

signed main(){
	std::ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n>>k;
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		add_edge(x,y);add_edge(y,x);
	}
	dfs1(1,0);dfs2(1,0);
	for(int i=1;i<=n;i++)ans+=f[i][0];
	cout<<ans/2;
	
	return 0;
}

标签:head,le,idx,int,siz,Jumps,CF771C,Tree,edges
From: https://www.cnblogs.com/little-corn/p/18157511

相关文章

  • CF911F Tree Destruction
    题目链接:https://www.luogu.com.cn/problem/CF911Fsolution:先求得树的直径,再求得在树的直径上的节点和不在树的直径上的节点。我们考虑优先删除不在直径上的节点,这样不会破坏树的直径,在删完了这些点之后再慢慢删直径上的点。#include<bits/stdc++.h>usingnamespacestd;#def......
  • AGC014D Black and White Trees
    传送门[AGC014D]BlackandWhiteTree给出一颗\(N\)个节点组成的树,每个节点都可以被染成白色或者黑色;有高桥(先手)和青木(后手)两个人————高桥可以把任意一个点染成白色,青木则可以把任意一个点染成黑色,每个点只可染色一次。重复上述操作直到所有点都被染色后,只执行一次执行......
  • 都2024年了,你还不知道git worktree么?
    三年前python大佬吉多·范罗苏姆(为Python程序设计语言的最初设计者及主要架构师)才知道gitworktree,我现在才知道,我觉得没啥丢人的。应用场景如果你正在feature的分支中开发新功能,线上版本紧急错误又需要你基于master做修复。可能有如下几种办法解决:解法1将本......
  • (复习)树上启发式合并(dsu on tree)入门U41492树上数颜色
    主要思想是树的重轻儿子之分使得时间复杂度为o(nlogn),神奇欲深入了解的这里:https://oi-wiki.org/graph/dsu-on-tree/点击查看代码#include<bits/stdc++.h>usingnamespacestd;typedefstructedge//边结构体{intto,next;}EDGE;//边相关数组EDGEe[100001<<1];......
  • UniTreeMenu只展开一个Item,点击主菜单时,不打开最后一个item
    设置:procedureTMainForm.UniTreeMenu1Click(Sender:TObject);varNode:TUniTreeNode;Ts:TUniTabSheet;FrC:TUniFrameClass;Fr:TUniFrame;FClassName,ShowInfo:string;beginNode:=UniTreeMenu1.Selected;ifNode.Tag>1000thenbeginTs:=Node.Data;......
  • Codeforces 1824C LuoTianyi and XOR-Tree
    考虑到肯定如果能在这个节点让子树的值尽量相同肯定更好,这样子不会与上面的操作相冲突。于是有个\(\text{DP}\)的思路。记\(f_{u,i}\)为\(u\)子树内叶子节点的值都变为\(i\)的最小代价。这个有一个很好的性质,就是\(\maxf_{u,i}-\minf_{u,i}=1\)。这是因为考......
  • P6018 [Ynoi2010] Fusion tree 题解
    题目链接:Fusiontree大部分人貌似用的边权01Trie,实际这题用点权01Trie类似文艺平衡树去写更方便。考虑两种常见的区间维护:线段树。使用的是父节点信息是归并了左右区间的信息,适用于不需要考虑父节点的贡献的信息。文艺平衡树。每个点就是一个信息,归并左右子树,外加当......
  • Causal Inference理论学习篇-Tree Based-From Uplift Tree to Uplift Forest
    upliftTree和causaltree一样,uplifttree[8]作为一种以分类任务为主的,同样是将因果效应apply到节点分割的标准中。区别是:causaltree:1)使用honest的方法;2)从effect的偏差和方差的角度切入指导树的构建,把分类问题转化为回归问题去做。3)逻辑上只支持两个treatment而uplifttree......
  • Causal Inference理论学习篇-Tree Based-Causal Forest
    广义随机森林了解causalforest之前,需要先了解其forest实现的载体:GENERALIZEDRANDOMFORESTS[6](GRF)其是随机森林的一种推广,经典的随机森林只能去估计labelY,不能用于估计复杂的目标,比如causaleffect,CausalTree、CauaslForest的同一个作者对其进行了改良。先定义一下矩估计......
  • [ABC240E] Ranges on Tree 题解
    [ABC240E]RangesonTree题解思路解析由题意可知,只要一个点的所有儿子节点都被确定了,那么当前节点也就被确定了。也就是说,只要确定了所有叶子节点,也就能一层层地确定所有节点,而叶子节点没有儿子节点不受此条件的约束,同时我们希望\(\max\limits^N_{i=1}R_i\)最小,所以我们把所......