【XSY1537】五颜六色的幻想乡 数学 生成树计数 拉格朗日插值
题目大意
有一个\(n\)个点\(m\)条边的图,每条边有一种颜色\(c_i\in\{1,2,3\}\),求所有的包括\(i\)条颜色为\(1\)的边,\(j\)条颜色为\(2\)的边,\(k\)条颜色为\(3\)的边的生成树的数量。
对\({10}^9+7\)取模。
\(n\leq 50\)
题解
如果\(\forall i,c_i=1\),就可以直接用基尔霍夫矩阵计算生成树个数。但是现在有三种颜色,不妨设\(c_i=2\)的边的边权为\(x\),\(c_i=3\)的边的边权为\(y\)。因为\(x\)的次数不会超过\(n-1\),所以可以设\(y=x^n\)。基尔霍夫矩阵可能是这样子的:
$$\begin{bmatrix}1+x&-1&-x\-1&1+xn&-xn\-x&-xn&x{n+1}\end{bmatrix}$$
这样的话直接高斯消元很明显会TLE,可以用FFT优化。FFT是在每次乘法时先做一次求值,做一次点值乘法,最后做一次插值。所以我们可以先在消元前做一次求值,消元时直接做点值乘法,最后再插值插回来。
因为答案的最高次不超过\(n(n-1)\),所以我们可以把\(n(n-1)+1\)个点带到行列式中,把每次得到的行列式保存下来,最后再用拉格朗日插值插回来。这里不能用高斯消元是因为高斯消元会直接TLE。
求行列式的总时间复杂度是\(O(n^2)\times O(n^3)=O(n^5)\),拉格朗日插值的时间复杂度是\(O({(n^2)}^2)=O(n^4)\),高斯消元的时间复杂度是\(O({(n^2)}^3)=O(n^6)\)。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
ll p=1000000007;
ll a[60][60];
int lx[10010];
int ly[10010];
int lc[10010];
ll x[3010];
ll y[3010];
ll c[3010];
ll b[3010];
ll d[3010];
ll l[3010];
ll ans[3010];
ll fp(ll a,ll b)
{
ll s=1;
while(b)
{
if(b&1)
s=s*a%p;
a=a*a%p;
b>>=1;
}
return s;
}
ll calc(int t)
{
int i,j,k;
ll s=1;
for(i=1;i<=t;i++)
{
for(j=i;j<=t;j++)
if(a[j][i])
break;
if(j>t)
return 0;
int x=j;
if(x>i)
{
s=-s;
for(j=i;j<=t;j++)
swap(a[i][j],a[x][j]);
}
for(j=i+1;j<=t;j++)
if(a[j][i])
{
ll d=a[j][i]*fp(a[i][i],p-2)%p;
for(k=i;k<=t;k++)
a[j][k]=(a[j][k]-a[i][k]*d%p)%p;
}
}
for(i=1;i<=t;i++)
s=s*a[i][i]%p;
s=(s+p)%p;
return s;
}
int main()
{
// freopen("count.in","r",stdin);
int n,m;
scanf("%d%d",&n,&m);
int i,j,k;
for(i=1;i<=m;i++)
scanf("%d%d%d",&lx[i],&ly[i],&lc[i]);
for(i=1;i<=n*n;i++)
{
x[i]=(i*1000+1)%p;
// x[i]=i%p;
ll px=fp(x[i],n);
memset(a,0,sizeof a);
for(j=1;j<=m;j++)
{
if(lc[j]==1)
{
a[lx[j]][lx[j]]++;
a[ly[j]][ly[j]]++;
a[lx[j]][ly[j]]--;
a[ly[j]][lx[j]]--;
}
else if(lc[j]==2)
{
(a[lx[j]][lx[j]]+=x[i])%=p;
(a[ly[j]][ly[j]]+=x[i])%=p;
(a[lx[j]][ly[j]]-=x[i])%=p;
(a[ly[j]][lx[j]]-=x[i])%=p;
}
else
{
(a[lx[j]][lx[j]]+=px)%=p;
(a[ly[j]][ly[j]]+=px)%=p;
(a[lx[j]][ly[j]]-=px)%=p;
(a[ly[j]][lx[j]]-=px)%=p;
}
}
y[i]=calc(n-1);
}
int t=n*n;
memset(c,0,sizeof c);
c[0]=1;
memset(ans,0,sizeof ans);
for(i=1;i<=t;i++)
for(j=t;j>=0;j--)
{
(c[j+1]+=c[j])%=p;
(c[j]=-c[j]*x[i])%=p;
}
for(i=1;i<=t;i++)
{
memcpy(d,c,sizeof d);
memset(b,0,sizeof b);
for(j=t;j>=0;j--)
{
b[j]=d[j+1];
d[j]=(d[j]+d[j+1]*x[i])%p;
d[j+1]=0;
}
ll s=0,px=1;
for(j=0;j<=t;j++)
{
s=(s+px*b[j])%p;
px=px*x[i]%p;
}
s=fp(s,p-2)*y[i]%p;
for(j=0;j<=t;j++)
b[j]=b[j]*s%p;
for(j=0;j<=t;j++)
ans[j]=(ans[j]+b[j])%p;
}
for(i=0;i<n;i++)
for(j=0;j<n-i;j++)
printf("%lld\n",(ans[j+n*(n-i-j-1)]%p+p)%p);
return 0;
}
【XSY1537】五颜六色的幻想乡 数学 生成树计数 拉格朗日插值的更多相关文章
- 幻想乡三连A:五颜六色的幻想乡
非常直接地构造 由于答案与生成树计数有关,所以一定要使用矩阵树定理,但这样就不能限制每种颜色的便使用的数量 我们构造$N^2$个关于$Ans_{x,y}$的方程,枚举将红色的边拆成$x$条,将蓝色的边 ...
- 【XSY1538】连在一起的幻想乡 数学 无向连通图计数
题目大意 给你\(n,p\),求\(n\)个点组成的所有无向连通图的边数的平方和模\(p\) \(n\leq 2000,p\leq {10}^9\) 题解 设\(m=\frac{n(n-1 ...
- [2016北京集训试题8]连在一起的幻想乡[dp+无向图计数]
Description Solution 本博客参考yww大佬的博客,为了加深理解我就自己再写一遍啦. 以下的“无向图”均无重边无自环. 定义f0[n]为n个点构成的无向图个数,f1[n]为n个点构成 ...
- luogu P4948 数列求和 推式子 简单数学推导 二项式 拉格朗日插值
LINK:数列求和 每次遇到这种题目都不太会写.但是做法很简单. 终有一天我会成功的. 考虑类似等比数列求和的东西 帽子戏法一下. 设\(f(k)=\sum_{i=1}^ni^ka^i\) 考虑\(a ...
- 生成树计数 Matrix-Tree 定理 学习笔记
一直都知道要用Matrix-Tree定理来解决生成树计数问题,但是拖到今天才来学.博主数学不好也只能跟着各位大佬博客学一下它的应用以及会做题,证明实在是不会. 推荐博客: https://www.cn ...
- 「SHOI2016」黑暗前的幻想乡 解题报告
「SHOI2016」黑暗前的幻想乡 sb题想不出来,应该去思考原因,而不是自暴自弃 一开始总是想着对子树做dp,但是状态压不起去,考虑用容斥消减一些条件变得好统计,结果越想越乱. 期间想过矩阵树定理, ...
- @总结 - 7@ 生成树计数 —— matrix - tree 定理(矩阵树定理)与 prüfer 序列
目录 @0 - 参考资料@ @0.5 - 你所需要了解的线性代数知识@ @1 - 矩阵树定理主体@ @证明 part - 1@ @证明 part - 2@ @证明 part - 3@ @证明 part ...
- [ZJOI2015]地震后的幻想乡(期望+dp)
题目描述 傲娇少女幽香是一个很萌很萌的妹子,而且她非常非常地有爱心,很喜欢为幻想乡的人们做一些自己力所能及的事情来帮助他们. 这不,幻想乡突然发生了地震,所有的道路都崩塌了.现在的首要任务是尽快让幻想 ...
- P4336 [SHOI2016]黑暗前的幻想乡
P4336 [SHOI2016]黑暗前的幻想乡 矩阵树定理(高斯消元+乘法逆元)+容斥 ans=总方案数 -(公司1未参加方案数 ∪ 公司2未参加方案数 ∪ 公司3未参加方案数 ∪ ...... ∪ ...
随机推荐
- Rikka with Subset HDU - 6092 (DP+组合数)
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some mat ...
- InvalidDataAccessResourceUsageException:mysql保留字引发的血案
org.springframework.dao.InvalidDataAccessResourceUsageException: could NOT EXECUTE statement; SQL [n ...
- Python_迭代器、生成器、列表推导式,生成器表达式
1.迭代器 (1)可迭代对象 s1 = ' for i in s1: print(i) 可迭代对象 示例结果: D:\Python36\python.exe "E:/Python/课堂视频/ ...
- HDFS的命令
.....Hdfs dfs -cat path hadoop fs - 等同 1 -ls 查看当前目录的文件和文件夹 2 -lsr 递归查看 3 -du 查看文件的大小 4-dus 查看文件夹中所有的 ...
- HDU 2001 计算两点间的距离
http://acm.hdu.edu.cn/showproblem.php?pid=2001 Problem Description 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离 ...
- python文件封装成*.exe文件(单文件和多文件)
环境:win10 64位 python3.7 单*.py文件打包Python GUI:程序打包为exe 一.安装Pyinstaller,命令pip install Pyinstaller,(大写的P ...
- Programming好文解读系列(—)——代码整洁之道
注:初入职场,作为一个程序员,要融入项目组的编程风格,渐渐地觉得系统地研究下如何写出整洁而高效的代码还是很有必要的.与在学校时写代码的情况不同,实现某个功能是不难的,需要下功夫的地方在于如何做一些防御 ...
- MyBatis全局配置文件的各项标签3
mapper 将sql映射注册到全局配置中,这个我们在上一章已经使用过了, resource 这个属性是用来引用类路径下的sql映射文件 url 这个属性是用来引用网络路径或磁盘路径下的sql映射文件 ...
- 如何在TypeScript中使用第三方JavaScript框架
一.安装typings 使用npm全局安装typings :npm install -g typings 安装成功. 二,搜索资源,支持模糊搜索:typings search base64 三.安装t ...
- websocket协议握手详解
最近使用tornado做长链接想着怎么着也要试试websocket协议吧.所以说干就干. 首先要知道websocket是基于http协议的,为什么这么说?因为从协议来说,websocket是借用了一部 ...