Loading [MathJax]/jax/output/CommonHTML/fonts/TeX/AMS-Regular.js

【JZOJ6569】【GDOI2020模拟】夕张的改造 (kaisou)

题目大意

给出一棵树,可以删除其中最多kk条边,再加上若干条边使得其还是一棵树,问这样的操作能得到多少种不同的树的形态(带编号)。

n50,0knn50,0kn

思路

一种升级版的生成树计数。
设树上的边权值为11,不存在的边权值为xx,则构造矩阵gg

  • ijij,则g[i][j]=g[i][j]=(i,j)(i,j)的权值的相反数。
  • i=ji=j,则g[i][j]=g[i][j]=ii相邻边的权值之和。
  • 矩阵树定理:构造上述矩阵后,该矩阵其任意一个余子式的行列式=
  • 求行列式的方法:用高斯消元把矩阵消成上三角矩阵后,对角线数字乘积即为其行列式的值。

现在x不确定,所以求出来的行列式实际上是一个多项式。这个多项式的xk的系数,就是使用k条边权为x的边的方案数,即删去原树中k条边,再加上k条边形成一棵树的方案数。那么问题就变成求这个多项式的系数了。
直接求系数不好做,我们可以考虑先求这个多项式的点值表达,即把x分别代换成n个不同的数求行列式,然后使用高斯消元或拉格朗日插值法还原系数表达。
最后把x0xk的系数加起来就是答案了。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long ll;
const int N=57;
const ll P=998244353;

int n,K;
int a[N][N],f[N];
ll sum,g[N][N][2],b[N][N],y[N],ans[N];
ll mtp[N],tmp[N],mtp1[N];

ll pow(ll a,ll b){
	ll ret=1;
	for(;b;a=a*a%P,b>>=1)if(b&1)ret=ret*a%P;
	return ret;
}
ll inv(ll x){return pow(x%P,P-2);}

ll solve(){
	for(int i=1;i<n;++i){
		for(int j=i+1;j<n;++j){
			ll res=b[j][i]*inv(b[i][i])%P;
			for(int k=1;k<n;++k)b[j][k]=(b[j][k]-res*b[i][k]%P+P)%P;
		}
	}
	ll ret=1;
	for(int i=1;i<n;++i)ret=ret*b[i][i]%P;
	return ret;
}

void domtp(){
	memset(tmp,0,sizeof(tmp));
	for(int i=0;i<n;++i)for(int j=0;j<2;++j)tmp[i+j]=(tmp[i+j]+mtp[i]*mtp1[j]%P)%P;
	memcpy(mtp,tmp,sizeof(tmp));
}

int main(){
	freopen("kaisou.in","r",stdin);
	//freopen("kaisou.out","w",stdout);
	scanf("%d%d",&n,&K);
	for(int i=2;i<=n;++i)scanf("%d",&f[i]),++f[i],a[i][f[i]]=a[f[i]][i]=1;
	for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)--g[i][j][a[i][j]],++g[i][i][a[i][j]];
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j)for(int k=1;k<=n;++k)b[j][k]=((g[j][k][0]+P)*i+(g[j][k][1]+P)%P)%P;
		y[i]=solve();
	}
	for(int i=1;i<=n;++i){
		ll pp=1;
		memset(mtp,0,sizeof(mtp));
		mtp[0]=1;
		for(int j=1;j<=n;++j)if(j!=i){
			mtp1[1]=1,mtp1[0]=P-j;
			domtp();
			pp=pp*(i-j+P)%P;
		}
		for(int j=0;j<n;++j)ans[j]=(ans[j]+mtp[j]*inv(pp)%P*y[i]%P)%P;
	}
	for(int i=0;i<=K;++i)sum=(sum+ans[i])%P;
	printf("%lld\n",sum);
	return 0;
}

作者:zjlcnblogs

出处:https://www.cnblogs.com/zjlcnblogs/p/12748500.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   gz-gary  阅读(391)  评论(0编辑  收藏  举报
编辑推荐:
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
阅读排行:
· dotnet 源代码生成器分析器入门
· 官方的 MCP C# SDK:csharp-sdk
· 从零开始:基于 PyTorch 的图像分类模型
· [WPF] 在RichTextBox中输出Microsoft.Extension.Logging库的
· 一步一步教你部署ktransformers,大内存单显卡用上Deepseek-R1
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示