CF917D-Stranger Trees【矩阵树定理,高斯消元】
2024-08-31 06:40:05
正题
题目链接:https://www.luogu.com.cn/problem/CF917D
题目大意
给出\(n\)个点的一棵树,对于每个\(k\)求有多少个\(n\)个点的树满足与给出的树恰好有\(k\)条边重合。
解题思路
矩阵树有一个统计所有树边权和的和用法,就是把变量变成一个形如\(wx+1\)的多项式,这样一次项系数的值就表示了固定选择一条边的\(w\)时其他边的方案数之和。
这题我们可以同理,对于在给出数上的边是\(x\),而其他就是\(1\)。那么最后询问\(x^k\)的系数就是答案了。
如果暴力套\(\text{NTT}\)不仅麻烦,而且跑的很慢过不了本题,考虑另一种求系数的方法。
我们假设答案是一个形如\(F(x)=\sum_{i=0}^{n-1}a_ix^i\)的\(n\)次项式,那么我们如果把\(n\)个\(x\)的值直接带入求出\(F\),然后用待定系数法的话我们就可以列出\(n\)个方程从而解出这个\(n\)项式的每一个系数。
时间复杂度\(O(n^4)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=110,P=1e9+7;
ll n,x[N],y[N];
ll power(ll x,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*x%P;
x=x*x%P;b>>=1;
}
return ans;
}
namespace Guass{
ll a[N][N],b[N];
void solve(){
for(ll i=1;i<=n;i++){
ll z=i;
for(ll j=i;j<=n;j++)
if(a[j][i]){z=j;break;}
swap(a[i],a[z]);swap(b[i],b[z]);
ll inv=power(a[i][i],P-2);
for(ll j=i;j<=n;j++)
a[i][j]=a[i][j]*inv%P;
b[i]=b[i]*inv%P;
for(ll j=i+1;j<=n;j++){
ll rate=P-a[j][i];
for(ll k=i;k<=n;k++)
(a[j][k]+=rate*a[i][k]%P)%=P;
(b[j]+=rate*b[i]%P)%=P;
}
}
for(ll i=n;i>=1;i--){
for(ll j=i+1;j<=n;j++)
(b[i]+=P-b[j]*a[i][j]%P)%=P;
}
return;
}
}
namespace Matrix{
ll a[N][N];
ll det(){
ll f=1,ans=1;
for(ll i=1;i<n;i++){
ll z=i;
for(ll j=i;j<n;j++)
if(a[j][i]){
if(j!=i)f=-f;
z=j; break;
}
swap(a[i],a[z]);
ll inv=power(a[i][i],P-2);
ans=ans*a[i][i]%P;
for(ll j=i;j<n;j++)
a[i][j]=a[i][j]*inv%P;
for(ll j=i+1;j<n;j++){
ll rate=P-a[j][i];
for(ll k=i;k<n;k++)
(a[j][k]+=rate*a[i][k]%P)%=P;
}
}
return ans*f;
}
void solve(ll w){
for(ll i=1;i<=n;i++)
for(ll j=1;j<=n;j++)
a[i][j]=P-1;
for(ll i=1;i<=n;i++)a[i][i]=n-1;
for(ll i=1;i<n;i++){
a[x[i]][x[i]]+=w-1;
a[y[i]][y[i]]+=w-1;
a[x[i]][y[i]]=P-w;
a[y[i]][x[i]]=P-w;
}
Guass::b[w]=det();
for(ll i=1,p=1;i<=n;i++,p=p*w%P)
Guass::a[w][i]=p;
return;
}
}
signed main(){
scanf("%lld",&n);
for(ll i=1;i<n;i++)
scanf("%lld%lld",&x[i],&y[i]);
for(ll i=1;i<=n;i++)Matrix::solve(i);
Guass::solve();
for(ll i=1;i<=n;i++)
printf("%lld ",Guass::b[i]);
return 0;
}
最新文章
- .NET 垃圾回收与内存泄漏
- 各种android应用模仿源码
- Android开发之Toast
- MAC 设置环境变量path的几种方法
- POI2012
- 如何订阅Form的自定义事件
- gradle基础的build文件模板_jetty
- [3D跑酷] DataManager
- 学习JS中的小问题
- 取消GridView/ListView item被点击时的效果
- hdu 3232 Crossing Rivers(期望 + 数学推导 + 分类讨论,水题不水)
- 阿里云Ubuntu部署java web(2) - 配置tomcat
- [笔试题目]使用Stringbuffer无 参的构造函数创建 一个对象时,默认的初始容量是多少? 如果长度不够使用了,自动增长多少倍?
- python2和python3关于列表推导的差别
- 利用python搭建Powersploit powershell脚本站点
- sql server 查看锁表SQL【转】
- 记录解决phpStudy报出403Forbidden问题的方法
- POJ 1661 (Help Jimmy )
- 工具使用-----Jmeter-脚本的录制
- Scala(四):对象
热门文章
- 依赖注入@Autowired@Primary@Quelifier使用
- nginx使用geo模块进行接口访问限制
- bootstrap 冻结表格,冻结表头
- Scan error on column index 1, name “created_at“: unsupported Scan, storing driver.Value type []uint8
- for循环操作(for...in、forEach)
- js在不同页面的导航背景不同 (设置网站公共头的导航)
- skynet 开启 https 配置
- 人生重开模拟器「GitHub 热点速览 v.21.36」
- Sentry-CLI 使用详解(2021 Sentry v21.8.x)
- 【数据库上】 第四讲 E-R模型基础知识