首页 > 其他分享 >ARC101E题解

ARC101E题解

时间:2024-12-25 15:32:41浏览次数:7  
标签:方案 连通 子树 匹配 int 题解 times ARC101E

前言

此片题解大致按照笔者做题思路进行讲解。

简要题意

有一棵树,树上有偶数个节点。你需要给这些点两两配对,一组已经配对的点会将两点之间的树边进行一次覆盖。一组合法方案需要满足树上所有边都被覆盖至少一次,求合法方案数。

数据范围:\(n\le5000\)。

思路

首先我们去观察题目性质,发现没有什么特殊的地方。我最开始只想到一个非常暴力的 \(dp\),设 \(f_{u,i}\) 表示以 \(u\) 为根的子树内有 \(i\) 个点已经匹配好的方案数。但是当我去考虑转移时,我发现他有很多种情况:

  1. \(u\) 一个儿子的子树内互相匹配,但是需要有一个点与外面的点匹配(不然这个子树与 \(u\) 之间的边就无法被覆盖);
  2. 一个子树内的点向 \(u\) 的其他子树匹配;
  3. 一个子树的点向 \(u\) 子树以外的点匹配。

或许还有一些没有罗列出来,但反正就是不可做。于是我们正难则反,考虑先求出不合法的情况,然后容斥做。

题解

如何求不合法的情况呢?我们可以通过钦定一些边不覆盖来容斥。比如当我计算到以 \(u\) 为根的子树时,我就去枚举 \(u\) 所在的连通块的大小,对于一个 \(u\) 的儿子 \(v\),分讨一下连通块是否包括 \(v\)。

具体的,我们设 \(f_{u,i}\) 表示以 \(u\) 为根的子树,\(u\) 所在连通块大小为 \(i\) 的方案数。对于 \(v\) 在连通块的时候,有转移:

\[f_{u,i-j}\times f_{v,j}\rightarrow f_{u,i},v\in{\operatorname{son}_u,j<i} \]

若 \(v\) 与 \(u\) 之间的边不覆盖,则有:

\[f_{u,i}\times f_{v,j}\rightarrow f_{u,i+j} \]

你乍一看这不就是树上背包吗?时间复杂度 \(O(n^2)\),可以通过此题!

现在我们已经基本找出状态转移的方程,但现在我们还需要思考一个问题:

一个点数为 \(k\) 的连通块,将里面的点不重不漏两两匹配的方案数

首先对于 \(k\) 为奇数的时候是无贡献的;所以只用考虑 \(k\) 为偶数的情况。考虑递推求解答案,设 \(s_k\) 表示点数为 \(k\) 的贡献。对于一个点,我有 \(k - 1\) 种选择方案,而剩下的 \(k-2\) 个点的方案是 \(s_{k-2}\),固可得递推式:\(s_{k}=(k-1)\times s_{k-2}\)。

但考虑到我们只是没有考虑这些方案中会有的不合法情况,所以需要稍微容斥一下,在转移的时候还需要给一个 \((-1)^k\)。

然后看到之前的 \(dp\),我们发现对于第一种情况合并两个连通块似乎不好计算方案,于是我们改写状态,设 \(f_{u,i}\) 表示以 \(u\) 为根的子树,\(u\) 所在连通块大小为 \(i\) 时不考虑 \(u\) 所在连通块中匹配情况的方案数,这样在合并两个连通块时我们就直接把系数乘上就行,所以最后第一种情况的转移式为:

\[f_{u,i}\leftarrow f_{u,i-j}\times f_{v,j}\times(-s_i) \]

最后答案就是 \(\sum\limits_{i}f_{1, i}\times s_i\)。

代码

void dfs(int u, int fa){
    sz[u] = f[u][1] = 1;
    for(int i = hd[u]; i; i = e[i].nxt){
        int v = e[i].to; if(v == fa)continue;
        dfs(v, u); copy(f[u], f[u] + 1 + sz[u], g);
        fill(f[u], f[u] + 1 + sz[u], 0);
        for(int j = 1; j <= sz[u]; ++j)for(int k = 1; k <= sz[v]; ++k)
            f[u][j] = del(f[u][j], mul(mul(f[v][k], s[k]), g[j])),
            f[u][j + k] = add(f[u][j + k], mul(g[j], f[v][k]));
        sz[u] += sz[v];
    }
}

标签:方案,连通,子树,匹配,int,题解,times,ARC101E
From: https://www.cnblogs.com/Nekopedia/p/18630529

相关文章

  • PyTorch 入门指南:安装流程、应用示例与问题解法
    安装PyTorch环境准备确保你的系统安装了Python。PyTorch支持Python3.6及以上版本。可以从Python官方网站(https://www.python.org/)下载并安装。建议使用虚拟环境(如venv或conda)来隔离项目依赖。以conda为例,你可以使用以下命令创建一个新的环境:condacreate-npytorch_env......
  • MySQL占用内存和SWAP问题解决
    背景发现公司的项目部署上,经常出现数据库占用内存很高(接近6G)的情况,而且还出现了SWAP使用到90%左右的水平。所以需要排查数据库使用内存的情况,看数据库为什么使用了这么多内存,而且会不会频繁使用交换空间。要解决的问题:数据库使用高内存数据库使用SWAP解决SWAP空间在......
  • [BZOJ4771] 七彩树 题解
    好题,又学两个思路。先把问题变简单一点,去掉深度限制,那么有两种做法:经典的前驱后继转化到二维数点。颜色相同的点按\(dfs\)序排序,每个点\(+1\),相邻两点\(lca-1\)。转化为区间求和。第二种相对实现简单。假如加上深度,我们可以离线问题,按深度顺序加点。要在线的话,只......
  • CF2043C 题解
    CF2043C题解题意给定一个除了\(-1,1\)之外,最多存在一个\(x,x\in[-10^9,10^9]\)的数的序列,求其子段和的所有可能值,从小到大输出。分析很容易就去思考如何从这个特殊的\(x\)入手。于是先排除这个特例,考虑全都是\(1,-1\)的情形,那么顺序从左到右不断加入\(a_i\),可以发现......
  • P6779 [Ynoi2009] rla1rmdq 题解
    Description给定一棵\(n\)个节点的树,树有边权,与一个长为\(n\)的序列\(a\)。定义节点\(x\)的父亲为\(fa(x)\),根\(rt\)满足\(fa(rt)=rt\)。定义节点\(x\)的深度\(dep(x)\)为其到根简单路径上所有边权和。有\(m\)次操作:1lr:对于\(l\lei\ler\),\(a_i\lef......
  • 【Web】2024“国城杯”网络安全挑战大赛决赛题解(全)
    最近在忙联通的安全准入测试,很少有时间看CTF了,今晚抽点时间回顾下上周线下的题(期末还没开始复习......
  • 题解 P9885【[Qingdao18A] Sequence and Sequence】
    具体数学还在发力!题目描述考虑下列两个序列\(P\)和\(Q\)。我们用\(P(i)\)表示序列\(P\)中的第\(i\)个元素,用\(Q(i)\)表示序列\(Q\)中的第\(i\)个元素:序列\(P\)是一个已排序的序列,其中,对于所有\(k\in\mathbb{Z^+}\),\(k\)在序列\(P\)中出现\((k+1)\)......
  • [THUSC2015] 异或运算 题解
    学到新思路了:求解\(k\)大值时,可以将所有元素放一块一起跑。考虑到\(n,q\)奇小无匹,我们便可以制造一个\(O(qn\logV)\)的代码。那么对于我们不想在时间复杂度中出现的\(m\),我们直接把他扔进可持久化\(Trie\)中销赃。再根据刚才那个思路,将\([u,d]\)中所有点扔进可持......
  • ZJOI2016 旅行者 题解
    ZJOI2016旅行者题解题目大意:给定一个\(n\timesm\)的网格图,相邻的四连通的点之间有给定边权的双向边,有\(Q\)个离线询问,问两个点之间的最短路。\(n\timesm\le2\times10^4,Q\le10^5\)。发现了吗?和上次省选组的三角剖分那道题很像,这种平面图上的最短路很有可能是分治......
  • 省选模拟题解
    \(T1\)题解题意:有一张\(n\)个点的有标号无向图,分为了\(k\)个连通块,第\(i\)个连通块的大小是\(s_i\),每个连通块都是完全图(节点之间两两有边)。要加\(k-1\)条边使得图连通,计算所有连边方案的权值和。假设第\(i\)个连通块被多加了\(d_i\)条边,那么该连边方案的权值为\(......