首页 > 其他分享 >[ARC101E] Ribbons on Tree 题解

[ARC101E] Ribbons on Tree 题解

时间:2024-09-12 21:46:18浏览次数:1  
标签:连通 容斥 int 题解 Tree 枚举 ARC101E 考虑 dp

[ARC101E] Ribbons on Tree 题解

其实算一道好题了。

首先考虑不相关的 simple 的 dp。平凡的想法是设 \(dp_{i,j}\) 表示 \(i\) 子树内有 \(j\) 个点还需要向上转移的方案数。转移式大概是个 \(dp_{x,i+j}=dp_{y,i+j-1}+(dp_{p,i-1}+dp_{q,j-1})\) 之类的东西。这样的 dp 是 \(O(n^3)\) 的,并且难以优化。于是考虑放弃这个想法。

由于 \(n\le5000\),图上问题我们考虑容斥来计算。考虑这个常见的容斥:设 \(s(i)\) 表示 钦定了 \(i\) 条边不选择,而不管其它边的方案数。容易得到 \(\text{ans}=\sum s(i)(-1)^i\)。

考虑钦定边不选择的操作如何实现。考虑钦定一些边不选之后树会变成一些个连通块。这样一来我们尝试考虑依据连通块来 dp。那么对于每一个连通块里的点我们是可以任意连边的,并且容易得到对于 \(n\) 个点的树两两任意连边方案数是 \(\sum_{i=1}^{\frac{n}{2}}2\times i-1\) 的。现在考虑设出状态。

对于图上计数问题通常的策略是枚举 \(1\) 号点的连通块大小,那么我们尝试在本题中这么做。于是设 \(dp_{i,j}\) 表示 \(i\) 子树中 \(i\) 的连通块大小为 \(j\) 而不计这个连通块内部的方案数,即不考虑 \(s(j)\)。

那么转移方程就是好得到的,我们枚举点 \(x\) 的 \(i=siz_x\),\(y\) 的 \(j=siz_y\),于是枚举 \((x,y)\) 选还是不选。如果选择做正的贡献,反之做负的贡献,通过这样的操作容斥计算方案数即可。

对于时间复杂度,事实上枚举 \(i,j\) 的操作的复杂度相当于对树上的每一个点对 \((x,y)\) 在 LCA 处枚举了一遍,因此时间复杂度 \(O(n^2)\)。

整体上本题充分地考察选手综合运用容斥和 dp 知识解决问题的能力,环环相扣,解题逻辑清晰。是一道好题。

代码:

#include <bits/stdc++.h>
#define N 5005
#define int long long
#define mod 1000000007
using namespace std;
int n;
struct Node {
	int to, nxt;
} e[N << 1];
int head[N], cnt;
void add(int u, int v) {
	e[++cnt].to = v;
	e[cnt].nxt = head[u];
	head[u] = cnt;
}
int f[N][N], g[N];
int bas[N];
int siz[N];
void dfs(int x, int fa) {
	siz[x] = f[x][1] = 1;
	for (int i = head[x]; i; i = e[i].nxt) {
		int y = e[i].to;
		if (y == fa)
			continue;
		dfs(y, x);
		for (int j = 1; j <= siz[x]; j++)
			for (int k = 1; k <= siz[y]; k++) {
				if (j + k <= n)
					g[j + k] = (g[j + k] + f[x][j] * f[y][k] % mod) % mod;
				g[j] = (g[j] - f[x][j] * f[y][k] % mod * bas[k] % mod + mod) % mod;
			}
		siz[x] += siz[y];
		for (int j = 1; j <= siz[x]; j++)
			f[x][j] = g[j], g[j] = 0;
	}
}
int ans;
signed main() {
	cin >> n;
	for (int i = 1; i < n; i++) {
		int x, y;
		scanf("%lld%lld", &x, &y);
		add(x, y);
		add(y, x);
	}
	bas[0] = 1;
	for (int i = 2; i <= n; i += 2)
		bas[i] = bas[i - 2] * (i - 1) % mod;
	dfs(1, 0);
	for (int i = 2; i <= n; i += 2)
		ans = (ans + f[1][i] * bas[i] % mod) % mod;
	cout << ans << "\n";
	return 0;
}

标签:连通,容斥,int,题解,Tree,枚举,ARC101E,考虑,dp
From: https://www.cnblogs.com/Rock-N-Roll/p/18411164

相关文章

  • WPF 什么时候 VisualTreeHelper.GetDescendantBounds 将返回无穷大
    本文将和大家介绍在什么情况下WPF将会在调用VisualTreeHelper.GetDescendantBounds方法时,返回一个无穷大的范围尺寸在WPF的容器控件的里层元素的RenderTransform包含NaN将会导致对上层容器调用VisualTreeHelper.GetDescendantBounds返回无穷大返回的矩形范围是-∞,......
  • 题解 力扣 LeetCode 105 从前序与中序遍历序列构造二叉树 C/C++
    题目传送门:105.从前序与中序遍历序列构造二叉树-力扣(LeetCode)https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/每次在中序遍历序列片段中找到前序遍历序列队首,这是该层的根节点该位置左侧是左子树,右侧是右子树再......
  • P3267 [JLOI2016/SHOI2016] 侦察守卫 题解
    P3267[JLOI2016/SHOI2016]侦察守卫题解\(n\le5\times10^5,D\le20\)的数据范围显然想到\(O(nd)\)的树形dp。考虑\(d\)这一维的状态设计。考虑\(i\)子树中的情况分为全部被覆盖和未全部被覆盖两种。对于第一种,显然我们要考虑子树中能向上覆盖影响的点的个数,于是设......
  • P11030 『DABOI Round 1』Blessings Repeated题解
    P11030『DABOIRound1』BlessingsRepeated题解【形式化题意】给定一个正整数\(k\)和两个字符串\(S,T\)。设字符串\(s\)为\(k\)个字符串\(S\)首尾相接得到的字符串,\(n=\verts\vert,m=\vertT\vert\)。设答案集合\(P=\{(i_0,i_1,\dots,i_{m-1})\mid0\lei......
  • CTS2024 题解
    \(\text{ByDaiRuiChen007}\)D1T1.水镜ProblemLink给定\(a_1\sima_n\),求多少个\([l,r]\)满足存在实数\(L\),将若干个\(a_i\)变成\(2L-a_i\)后\(a_l\sima_r\)严格递增。数据范围:\(n\le10^6\)。考虑钦定\(i-1\)翻转/不翻转,\(i\)翻转/不翻转,容易发现......
  • 【题解】Solution Set - NOIP2024集训Day27 树形 dp
    【题解】SolutionSet-NOIP2024集训Day27树形dphttps://www.becoder.com.cn/contest/5521「HDU4661」MessagePassing「BZOJ3935」Rbtree「ARC101E」RibbonsonTree「AGC034E」CompleteCompress「COCI2014.10」Kamp「SCOI2015」小凸玩密室「AGC008F」Black......
  • 记录一下,把tree中的部分数据剔除
      <scriptsetuplang="ts">import{js_beautifyasbeautify}from"js-beautify";importhljsfrom"highlight.js";import"highlight.js/styles/atom-one-dark.css";consttree=ref([{name:"第一层&......
  • LOJ4222 「IOI2024」马赛克上色 题解
    题目描述给定长为\(n\)、下标从零开始的\(01\)序列\(x,y\),保证\(x_0=y_0\)。令\(col_{0,j}=x_j,col_{i,0}=y_i\),对\(\forall1\lei\ltn,1\lej\ltn\),\(col_{i,j}=[col_{i-1,j}=0\andcol_{i,j-1}=0]\)。\(q\)次询问,给定\(u,d,l,r\),求\(\sum_{i=u}^d......
  • TreeMap源码详解—彻底搞懂红黑树的平衡操作
    介绍TreeSet和TreeMap在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说TreeSet里面有一个TreeMap(适配器模式)。JavaTreeMap实现了SortedMap接口,也就是说会按照key的大小顺序对Map中的元素进行排序,key大小的评判可以通过其本身的自然顺序(naturalordering),也可以通......
  • 树(tree)和哈希算法(Hash)
    树由n个节点组成的有限集。有一个根节点;其他节点只有一个前驱节点,但可以有多个后继节点。叶子节点(终端结点):只有前驱结点没有后继结点结点度:子节点的个数称之为度树的(广)度:树中各节点度的最大值 深度:从根节点到最底层节点的层数森林:n个互不相交的树的集合二叉树:任意一个节点......