【做题记录】CF1039D You Are Given a Tree

  • \(\text{CF1039D You Are Given a Tree }\)

    • 算法:根号分治,\(\text{dp}\)

题目:

有一棵 \(n\) 个节点的树。

其中一个简单路径的集合被称为 \(k\) 合法当且仅当:

树的每个节点至多属于其中一条路径,且每条路径恰好包含 \(k\) 个点。

对于 \(k\in [1,n]\),求出 kk 合法路径集合的最多路径数 即:设 \(k\) 合法路径集合为 \(S\),求最大的 \(|S|\)

\(n \le 10^5\)

题解:

首先考虑一个贪心。

在一棵子树中尽可能地最大化完整路径条数。其次最大化未完成的链的长度。

然后进行合并时,先尝试与子树拼接,不行则往上延伸。

不过一次 \(O(n)\)

\(f_k\) 表示对于给定 \(k\) 的答案。

显然有 \(f_k\le \left\lfloor\dfrac{n}{k}\right\rfloor\)

考虑 \(k\) 的取值。

\(k\in [1,\sqrt n]\),共 \(\sqrt n\) 种;

\(k>\sqrt n\),亦为 \(\sqrt n\)

所以 \(f_k\) 的取值个数为 \(O(\sqrt n)\) 级别的。

然后 \(f\) 显然单调。

所以在边界上二分即可。

伪代码:

 
f[n]<=f[n-1]<=...<=f[1]

x=f[n];

check(x){
	int l=1,r=n;
	while(l<=r){
		int mid=(l+r)>>1;
		if(check(mid)<x){
			l=mid+1;
			res=mid;
		}
		else r=mid-1;
	}
	...
}

时间复杂度 \(O(n\sqrt n\log n)\)

posted @ 2022-01-07 19:35  trsins  阅读(41)  评论(0编辑  收藏  举报