[Matrix-Tree][插值][容斥][prufer序列][DP]夕张的改造

  • 源自 krydom 大爷的 FJ 省冬令营模拟赛题

Statement

  • 给定一棵 \(n\) 个点的树和一个参数 \(k\)
  • 每次操作可以选出树上的一条边删掉,然后再加一条边,使得操作之后还是一棵树
  • 求 \(k\) 次操作能得到多少种不同的树,对 \(998244353\) 取模
  • \(n\le 50\)(原题数据范围)
  • \(n\le 2000\)(加强版)
  • \(n\le 10^5\)(我不会,可以问 PinkRabbit

Solution 1:Matrix-Tree 矩阵树定理+拉格朗日插值 (std)

  • 树有两种常用的计数工具:Matrix-Tree 定理和 prufer 序列
  • 标解的做法是 Matrix-Tree 矩阵树定理
  • 易得我们要求的就是有多少棵树和原树的不同的边数 \(\le k\)
  • 考虑矩阵树定理的本质:求所有生成树的边权积之和
  • 于是我们考虑一个完全图,把每条边定权,如果这条边在原树上则权值为 \(1\),否则为 \(x\)
  • 这样对这个图求一遍 Matrix-Tree 之后得到的答案是一个多项式,\(x^i\) 表示不同的边数恰好为 \(i\) 的生成树个数
  • 这样有一个问题:高斯消元求行列式的复杂度为 \(O(n^3)\),多项式运算的复杂度为 \(O(n^2)\)(用 FFT 可能在常数上还比不过平方),总复杂度 \(O(n^5)\),不太能过
  • 不过最终答案的多项式次数只有 \(n-1\),我们考虑插值,把每条边的权值改为 \(n\) 个点值,可以取 \(1\) 到 \(n\)
  • 这样高斯消元时,多项式乘法就变成了点乘,可以 \(O(n)\) 计算,复杂度为 \(O(n^4)\),可以通过此题

Solution 2:容斥+prufer 序列+树形 DP

  • 如果你做过「WC2019」数树的话,你会发现这是数树的 \(op=1\) 弱化版
  • 考虑如何计算不同的边数恰好为 \(k\) 的方案数
  • 考虑容斥:
  • \[\sum_{m=0}^{k}(-1)^{k-m}\binom{n-1-m}{k-m}f(m)\]
  • \(f(m)\) 表示选出一个大小为 \(n-1-m\) 的边集并让它们和原树相同的方案数,\(\binom{n-1-m}{k-m}\) 的含义是枚举这个 \(f(m)\) 所在的大小为 \(k\) 的集合是哪个
  • 显然 \(f(m)\) 也可以看成原树删掉 \(m\) 条边分成 \(m\) 个连通块之后再连 \(m\) 条边组成一个新树的方案数
  • 可以使用 prufer 序列或 Matrix-Tree 矩阵树定理推出一个结论:
  • \(n=\sum_{i=1}^ma_i\),\(m\) 个连通块,大小分别为 \(a_{1\dots m}\),再加 \(m-1\) 条边形成树的方案数为:
  • \[n^{m-2}\prod_{i=1}^ma_i\]
  • 显然对于所有把原树划分成 \(m\) 个连通块的方案,\(n^{m-2}\) 是确定的,于是我们只需关注 \(\prod_{i=1}^ma_i\)
  • 于是对这个东西进行树形 DP:\(f[u][i][j]\) 表示 \(u\) 的子树选出了 \(i\) 个连通块,其中根所在的连通块大小为 \(j\),除根所在之外的所有连通块大小积之和
  • 大力转移,还是 \(O(n^4)\)
  • 和数树那题一样,如果利用 \(\prod_{i=1}^ma_i\) 的组合意义(每个连通块里选一个点的方案数)可以设计一个新的状态 \(f[u][i][0/1]\) 表示 \(u\) 的子树选出了 \(i\) 个连通块,第三维表示是否已经选出了一个点,这样的复杂度 \(O(n^2)\)

Solution 3

  • 我不会,可以问 PinkRabbit

Code

  • 咕咕咕

原文地址:https://www.cnblogs.com/xyz32768/p/12233031.html

时间: 2024-07-30 22:22:19

[Matrix-Tree][插值][容斥][prufer序列][DP]夕张的改造的相关文章

2669[cqoi2012]局部极小值 容斥+状压dp

2669: [cqoi2012]局部极小值 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 774  Solved: 411[Submit][Status][Discuss] Description 有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次.如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点)都小,我们说这个格子是局部极小值. 给出所有局部极小值的位置,你的任务是判断有多少个可能的矩阵. Input 输入第一行包含两个整数

HDU - 6314:Matrix (广义容斥)(占位)

Samwell Tarly is learning to draw a magical matrix to protect himself from the White Walkers. the magical matrix is a matrix with n rows and m columns, and every single block should be painted either black or white. Sam wants to know how many ways to

[CTS2019]氪金手游(容斥+树形背包DP)

降智好题.本蒟蒻VP时没想到怎么做被题面迷惑了,只会20分的“好”成绩.简直自闭了. 首先显然度为0的点是白给的,根据等比数列求和公式即可求得.然后考虑这个树如果是一颗外向树,就是每个点先父亲再自己.然后直接DP,令f[i][j]表示子树i内Σw=j的概率,转移时直接用背包转移一发即可.边是正向的直接转移,反向的加上去掉该限制的答案,并减去反向的答案.复杂度显然是O(n2) #include<bits/stdc++.h> using namespace std; const int N=101

HUST 1569(Burnside定理+容斥+数位dp+矩阵快速幂)

传送门:Gift 题意:由n(n<=1e9)个珍珠构成的项链,珍珠包含幸运数字(有且仅由4或7组成),取区间[L,R]内的数字,相邻的数字不能相同,且旋转得到的相同的数列为一种,为最终能构成多少种项链. 分析:这是我做过的最为综合的一道题目(太渣了),首先数位dp筛选出区间[L,R]内的幸运数字总数,dp[pos]表示非限制条件下还有pos位含有的幸运数字个数,然后记忆化搜索一下,随便乱搞的(直接dfs不知会不会超时,本人做法900+ms险过,应该直接dfs会超时),再不考虑旋转相同的情况,可以

青云的机房组网方案(简单+普通+困难)(虚树+树形DP+容斥)

题目链接 1.对于简单的版本n<=500, ai<=50 直接暴力枚举两个点x,y,dfs求x与y的距离. 2.对于普通难度n<=10000,ai<=500 普通难度解法挺多 第一种,树形dp+LCA 比赛的时候,我猜测对于不为1的n个数,其中两两互质的对数不会很多,肯定达不到n^2 然后找出所有互质的对数,然后对为1的数进行特殊处理.(初略的估计了下,小于500的大概有50个质数,将n个数平均分到这些数中,最后大概有10000*50*200=10^7) 对所有的非1质数对,采用离

【XSY3156】简单计数II 容斥 DP

题目大意 定义一个序列的权值为:把所有相邻的相同的数合并为一个集合后,所有集合的大小的乘积. 特别的,第一个数和最后一个数是相邻的. 现在你有 \(n\) 种数,第 \(i\) 种有 \(c_i\) 个.求所有不同的序列的权值的和. \(n\leq 50,c_i\leq 100\) 题解 考虑第一个数和最后一个数不相邻时怎么做. 记 \(g_{i,j}\) 为出现了 \(i\) 次的数分成 \(j\) 个集合,所有集合大小的乘积的和. \[ g_{i,j}=\sum_{k=1}^ig_{i-k,

[bzoj3622]已经没有什么好害怕的了——容斥or二项式反演+DP

题目大意: 给定两个长度为\(n\)的序列,求有多少种匹配方式,使得\(a_i<b_i\)的个数恰好为\(k\)个. 思路: 据说是一道二项式反演的经典例题了. 首先如果要求正好等于\(k\)个的是不太好求的,我们可以考虑求出至少为\(k\)个的方案数. 首先先把两个序列都按照从小到大的顺序排好序,然后以序列\(b\)为对象dp. 我们设\(f_{i,j}\)表示前\(i\)个数里面强制确定了\(j\)个\(a_i<b_i\)关系的方案数,记\(c_i\)表示在\(a\)中有多少个数<\

Codeforces 611C New Year and Domino DP+容斥

"#"代表不能放骨牌的地方,"."是可以放 500*500的矩阵,q次询问 开两个dp数组,a,b,a统计横着放的方案数,b表示竖着放,然后询问时O(1)的,容斥一下, 复杂度O(n^2+q) #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cstdlib> #include<cmat

hdu-5794 A Simple Chess(容斥+lucas+dp)

题目链接: A Simple Chess Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) Problem Description There is a n×m board, a chess want to go to the position (n,m) from the position (1,1).The chess is able to go to position (