Wannafly挑战赛23F-计数【原根,矩阵树定理,拉格朗日插值】
正题
题目链接:https://ac.nowcoder.com/acm/contest/161/F
题目大意
给出\(n\)个点的一张图,求它的所有生成树中权值和为\(k\)的倍数的个数。输出答案对\(p\)取模
\(1\leq n,k\leq 100,1\leq m\leq 10^4,p\in[2,10^9]\cup Pri\)
数据保证\(k\equiv 1(mod\ p)\)
解题思路
一个想法是把一条边权看做\(x^w\)的多项式,用矩阵树定理乘起来后\(k\)的倍数的系数和就是答案。
但是这样系数是\(nk\)个,显然搞不定。
类似于CF917D-StrangerTree的做法我们可以带入若干个值然后跑矩阵数之后求出若干个点值。
但是这里是\(k\)的倍数,我们要模拟卷积,可以带入\(k\)个\(g\)满足\(g^k=1\)的就可以了。
这里保证了\(k\equiv 1(mod\ p)\),所以我们求出\(p\)的原根\(g\)然后带入\(g^{\frac{p-1}{k}\times i}(i\in[0,k-1])\)就可以了。
然后直接拉插求出\(x=0\)的点值就好了。
时间复杂度\(O(n^3k)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;
const ll N=110;
struct node{
ll x,y,w;
}e[N*N];
ll n,m,k,P,g,x[N],y[N];
vector<ll> p;
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;
}
void Prime(){
ll x=P-1;
for(ll i=2;i*i<=x;i++)
if(x%i==0){
p.push_back(i);
while(x%i==0)x/=i;
}
if(x>1)p.push_back(x);
}
bool check(ll x){
for(ll i=0;i<p.size();i++)
if(power(x,(P-1)/p[i])==1)return 0;
return 1;
}
namespace Matrix{
ll a[N][N];
ll det(ll v){
memset(a,0,sizeof(a));
ll ans=1;
for(ll i=1;i<=m;i++){
ll x=e[i].x,y=e[i].y,w=power(v,e[i].w);
(a[x][y]+=P-w)%=P;(a[y][x]+=P-w)%=P;
(a[x][x]+=w)%=P;(a[y][y]+=w)%=P;
}
ll f=0;
for(ll i=1;i<n;i++){
for(ll j=i;j<n;j++)
if(a[j][i]){
if(i==j)break;
swap(a[i],a[j]);
f^=1;break;
}
ans=ans*a[i][i]%P;
ll inv=power(a[i][i],P-2);
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;
}
}
return f?(P-ans):ans;
}
}
signed main()
{
scanf("%lld%lld%lld%lld",&n,&m,&k,&P);
Prime();g=1;
while(!check(g))
g++;
for(ll i=1;i<=m;i++)
scanf("%lld%lld%lld",&e[i].x,&e[i].y,&e[i].w);
for(ll i=1;i<=k;i++){
x[i]=power(g,(P-1)/k*(i-1));
y[i]=Matrix::det(x[i]);
}
ll ans=0;
for(ll i=1;i<=k;i++){
ll tmp=1;
for(ll j=1;j<=k;j++)
if(i!=j)tmp=tmp*(P-x[j])%P*power(x[i]-x[j],P-2)%P;
(ans+=tmp*y[i]%P)%=P;
}
printf("%lld\n",(ans+P)%P);
return 0;
}
Wannafly挑战赛23F-计数【原根,矩阵树定理,拉格朗日插值】的更多相关文章
- 牛客Wannafly挑战赛23F 计数(循环卷积+拉格朗日插值/单位根反演)
传送门 直接的想法就是设 \(x^k\) 为边权,矩阵树定理一波后取出 \(x^{nk}\) 的系数即可 也就是求出模 \(x^k\) 意义下的循环卷积的常数项 考虑插值出最后多项式,类比 \(DFT ...
- bzoj1016 [JSOI2008]最小生成树计数——Kruskal+矩阵树定理
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 从 Kruskal 算法的过程来考虑产生多种方案的原因,就是边权相同的边有一样的功能, ...
- BZOJ 1016 最小生成树计数(矩阵树定理)
我们把边从小到大排序,然后依次插入一种权值的边,然后把每一个联通块合并. 然后当一次插入的边不止一条时做矩阵树定理就行了.算出有多少种生成树就行了. 剩下的交给乘法原理. 实现一不小心就会让程序变得很 ...
- 洛谷4208 JSOI2008最小生成树计数(矩阵树定理+高斯消元)
qwq 这个题目真的是很好的一个题啊 qwq 其实一开始想这个题,肯定是无从下手. 首先,我们会发现,对于无向图的一个最小生成树来说,只有当存在一些边与内部的某些边权值相同的时候且能等效替代的时候,才 ...
- [spoj104][Highways] (生成树计数+矩阵树定理+高斯消元)
In some countries building highways takes a lot of time... Maybe that's because there are many possi ...
- 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)
1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...
- spoj104 highways 生成树计数(矩阵树定理)
https://blog.csdn.net/zhaoruixiang1111/article/details/79185927 为了学一个矩阵树定理 从行列式开始学(就当提前学线代了.. 论文生成树的 ...
- @总结 - 7@ 生成树计数 —— matrix - tree 定理(矩阵树定理)与 prüfer 序列
目录 @0 - 参考资料@ @0.5 - 你所需要了解的线性代数知识@ @1 - 矩阵树定理主体@ @证明 part - 1@ @证明 part - 2@ @证明 part - 3@ @证明 part ...
- CSU 1805 Three Capitals(矩阵树定理+Best定理)
http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1805 题意: A和B之间有a条边,A和G之间有b条边,B和G之间有c条边.现在从A点出发走遍所 ...
随机推荐
- git忽略文件夹提交以及gitignore修改后不生效的解决办法
1.在 .gitgnore 文件加入需要忽略的问价夹正则表达式: 在配置完以后提交代码,你可能会发现git忽略配置不生效! 解决办法,将缓存的文件重新添加一下即可 2.打开命令行,将下面三个命令复制粘 ...
- mysql 数据库 分表后 怎么进行分页查询?Mysql分库分表方案?
Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. m ...
- WPF---数据模板(一)
一.场景模拟 假设我们现在有如下需求: 我们需要在ListBox中的每个Item中显示某个成员的姓名.年龄以及喜欢的颜色,点击Item的时候,会在右边显示详细信息,同时也想让ListBox的样式变得好 ...
- linux(3)--------SSH工具的安装使用
0.一般安装服务端的Linux ssh是默认安装的可以运行ssh localhost测试一下是否可以链接 1.SSH是什么 1)ssh:Secure Shell 安全外壳协议 2)建立在应用层基础上 ...
- mzy,struts学习(一)
大家都在讲struts已经过时了,现在都是前后台分离,没有必要去学一个淘汰的框架,但是怎么讲呢?我觉得,struts能够流行那么多年,肯定有它的原因,肯定有很多优秀和好的地方,有一个指导过我的人给我讲 ...
- 【MATLAB】常用命令快速入门,国赛加油
矩阵运算 矩阵的基本生成 m1 = 1:5 % 生成行矩阵[1,2,3,4,5] m2 = 1:2:10 % 起点:步长:终点 [1,3,5,7,9] linspace(x1,x2,n) % 生成 n ...
- leaflet加载离线OSM(OpenStreetMap)
本文为博主原创,如需转载需要署名出处. leaflet作为广为应用的开源地图操作的API,是非常受欢迎,轻量级的代码让使用者更容易操作. 废话不多说,下面直接给出范例. 首先在这个网站下载leafle ...
- Selenium4 IDE初体验
今天闲来无事,尝试了一番Selenium4的IDE,提供了录制和回放的功能.下面是对它的简单介绍. 安装 下载地址:https://www.selenium.dev/selenium-ide/ 在下载 ...
- (一)Superset 1.3图表篇——Table
本系列文章基于Superset 1.3.0版本.1.3.0版本目前支持分布,趋势,地理等等类型共59张图表.本次1.3版本的更新图表有了一些新的变化,而之前也一直没有做过非常细致的图表教程. 而且目前 ...
- idea字节码插件JClassLib——阅读JVM字节码
idea字节码插件JClassLib--阅读JVM字节码 生成字节码文件并查看 查看字节码文件的方式:javac 文件名.java 即可生成.class文件,但是这种方式不方便 java:是运行字节码 ...