首页 > 其他分享 >CF1385F Removing Leaves 题解

CF1385F Removing Leaves 题解

时间:2024-05-10 15:26:34浏览次数:32  
标签:p1 题解 Leaves v0 siz Removing sum dp define

看到题,感觉像树形DP,遂设计DP式子。

\(dp_u\) 表示以 \(u\) 为根的子树内最多能删多少次(不删 \(u\))。

那么每次子节点到父节点增加的贡献就是 \(\lfloor\frac{子树大小为1的子节点个数}{k}\rfloor\)。

得出式子 \(dp_u = \sum_{v\in son_u} dp_v + (\sum_{v\in son_u} [dp_v \times k=siz_v]) \div k\)。

为方便,我们把 \(\sum_{v\in son_u} [dp_v \times k=siz_v]\) 用 \(sum_u\) 表示。

这是一颗无根树,所以我们进行换根。

设从 \(u\) 换到 \(v\) ,变量 \(x\) 换根前为 \(x_0\) 换根后为 \(x\)。

\(dp_u=dp_{u0}-dp_{v0}-sum_{u0}\div k+(sum_{u0} - [dp_{v0} \times k = siz_{v0} - 1]) \div k\)

\(siz_u=n-siz_{v0}\)

\(siz_v=n\)

\(dp_v = dp_{v0} + dp_u - sum_{v0} \div k + (sum_{v0} + [dp_u \times k = siz_u - 1]) \div k\)

\(sum_v=sum_{v0}+[dp_u\times k = siz_u - 1]\)

虽然这些式子看起来很复杂,但是是因为我写的屎。

这样我们就得到了一个 \(O(n)\) 的解法,虽然 \(1e5\) 没必要。

点击查看代码
#include <bits/stdc++.h>

using namespace std;

#define fi first
#define se second

typedef unsigned long long ull;
typedef long long ll;
using Pii = pair<int , int>;
using Pll = pair<ll , ll>;

const int N = 2e5 + 5;
constexpr int INF = 0x3F3F3F3F;
constexpr ll INFl = 0x3F3F3F3F3F3F3F3F;
constexpr int P = 1e9 + 7;

#define typ int
#define writesp(x) write(x) , putchar(32)
#define writeln(x) write(x) , putchar(10)
inline char gc(){static char buf[100000] , *p1 = buf , *p2 = buf;return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 100000 , stdin) , p1 == p2) ? EOF : *p1 ++ ;}
#define getc gc
inline typ read(){typ x = 0; bool f = 0;char ch = getc();while(!isdigit(ch)){f |= (ch == '-');ch = getc();}while(isdigit(ch)){x = (x << 1) + (x << 3) + (ch ^ 48);ch = getc();}return (f ? -x : x);}
inline void write(typ x){if(x < 0) putchar('-') , x = -x;if(x / 10) write(x / 10);putchar(x % 10 ^ 48);}

int n , k;
struct edge {
	int to , nxt;
}e[N << 1];
int head[N] , cnt = 1;
void adde(int u , int v){
	e[ ++ cnt] = {v , head[u]};
	head[u] = cnt;
	e[ ++ cnt] = {u , head[v]};
	head[v] = cnt;
}
void clr(){
	cnt = 1;
	memset(head , 0 , sizeof head);
}

int dp[N] , siz[N] , sum[N];
void Dp(int u , int fa){
	siz[u] = 1;
	for(int i = head[u]; i; i = e[i].nxt){
		int v = e[i].to;
		if(v == fa) continue;
		Dp(v , u);
		siz[u] += siz[v];
		dp[u] += dp[v];
		sum[u] += (dp[v] * k == siz[v] - 1);
	}
	dp[u] += sum[u] / k;
}
int ans = 0;
void ch_rt(int u , int fa){
	ans = max(ans , dp[u]);
	for(int i = head[u]; i; i = e[i].nxt){
		int v = e[i].to;
		if(v == fa) continue;
		
		int dpu = dp[u] - dp[v] - sum[u] / k + (sum[u] - (dp[v] * k == siz[v] - 1)) / k;
		int sizu = siz[u] - siz[v];
		
		siz[v] = n;
		dp[v] = dp[v] + dpu - sum[v] / k + (sum[v] + (dpu * k == sizu - 1)) / k;
		sum[v] += (dpu * k == sizu - 1);
		
		ch_rt(v , u);
	}
}

void solve(){
	/*INIT*/
	clr();
	memset(dp , 0 , sizeof dp);
//	memset(siz , 0 , sizeof siz);
	memset(sum , 0 , sizeof sum);
	ans = 0;
	n = read() , k = read();
	for(int i = 1; i < n; ++ i){
		int u = read() , v = read();
		adde(u , v);
	}
	
	Dp(1 , 0);
	
	ch_rt(1 , 0);
	
	writeln(ans);
}

signed main(){
	int T = read();
	while(T -- ) solve();
	
	return 0;
}

标签:p1,题解,Leaves,v0,siz,Removing,sum,dp,define
From: https://www.cnblogs.com/TongKa/p/18184418

相关文章

  • 洛谷 P1031 [NOIP2002 提高组] 均分纸牌 题解
    题目简述有$N$堆纸牌,编号分别为$1,2,\ldots,N$。每堆上有若干张,但纸牌总数必为$N$的倍数。可以在任一堆上取若干张纸牌,然后移动。移牌规则为:在编号为$1$堆上取的纸牌,只能移到编号为$2$的堆上;在编号为$N$的堆上取的纸牌,只能移到编号为$N-1$的堆上;其他堆上取的纸牌,可......
  • 洛谷 P1012 [NOIP1998 提高组] 拼数 题解
    题目简述设有$n$个正整数$a_1\dotsa_n$,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。题目分析定义设$X$为数字$x$的字符串形式。$A+B$表示字符串$A$和字符串$B$相连组成的字符串。思路既然要构造最优解,显然如果有不优的情况的话,就需要对序列进行......
  • 一本通蓝皮题解
    最小生成树1486:【例题1】黑暗城堡求最短路径生成树的个数先求出根节点到各点的最短路径然后统计每个点的答案个数如果一个节点到1号节点的最短路=另一个和它有连边的节点到根节点的最短路+它们两个节点之间的直接距离这个点的个数++最后用乘法原理统计答案将每个点的......
  • LLaMA-Factory 训练 Llama3-Chinese-8B-Instruct 相关报错问题解决
    模型路径up主为llama中文社区模型地址https://www.modelscope.cn/models/FlagAlpha/Llama3-Chinese-8B-Instruct/summarysysinfov10032gnvcc--versioncuda11.8pythonimporttorchprint(torch.version)13.11pipinstallflash_attntimeout2下载whl报这个错......
  • text-generation-webui 推理模型Qwen1.5-7B-Chat相关报错问题解决
    推理代码text-generation-webui推理模型Qwen1.5-7B-Chatsysinfo nvcc--versioncuda11.8importtorch>>>print(torch.__version__)1路径错误2依赖没安装ImportError:Thismodelingfilerequiresthefollowingpackagesthatwerenotfoundinyourenvironme......
  • [国家集训队] happiness 题解
    发现可以做如下建图:对于前两组输入,从\(s\)向所有代表学生的点连一条边,容量为其学习文科的喜悦值;从所有代表学生的点向\(t\)连一条边,容量为其学习理科的最大值。对于后四组输入,建两个点\(x,y\),从\(s\)向\(x\),从\(y\)向\(t\)分别连容量为相邻两人同时学文/理时额......
  • [题解]CF1907G Lights
    CF1907GLights我们可以把灯抽象成节点,而开关抽象成无向边(重边算作\(1\)条)。显然每个连通块要么是一棵树,要么是一棵基环树。对于基环树,我们把它看做若干棵树处理,最后我们再考虑如何处理环。如下图,这是一棵树,黄色的点表示亮灯。我们选定任意一条边,可以改变子节点和父节点的状......
  • CodeForces 1967D Long Way to be Non-decreasing 题解
    题意简述yzh喜欢单调不降序列。她有一个序列\(a\),最初为\(a_1,\ldots,a_n\),其中每个元素都在\([1,m]\)内。她希望使序列变得单调不降,为此,她有一个序列$b_1\ldotsb_m$,每个元素也在\([1,m]\)内。她可以进行若干次操作,一次操作定义为:选择一个集合\(S\subseteq......
  • CF1967C题解
    CF1906D这里更容易进入且有翻译题意对于数组\(a\),有函数\(f(a)\),设数组\(s=f(a)\),则对于每一个\(s_i\),都有:\[s_i=\left(\sum^{i}_{j=(i\operatorname{\&}(i-1))+1}{a_j}\right)\]其中\(\&\)表示按位与运算。对于一个正整数\(k\),函数\(f^k(a)\)定义如......
  • P10429 [蓝桥杯 2024 省 B] 拔河 题解
    思路通过动态规划计算出所有连续子序列的力量值之和,并将其存储在一个数组中然后排序,遍历一遍数组,找到相邻两个力量值之和的差的绝对值的最小值,然后输出这个答案就行了。时间复杂度大概是\(O(n^2\logn)\)。来个python的代码defmin_power_diff(n,a):#计算所有连续子序列......