luoguP6624 [省选联考 2020 A 卷] 作业题(莫比乌斯反演,矩阵树定理)
luoguP6624 [省选联考 2020 A 卷] 作业题(莫比乌斯反演,矩阵树定理)
题外话:
Day2一题没切。
我是傻逼。
题解时间
某种意义上说刻在DNA里的柿子,大概是很多人学莫反做的第一题的套路。
$ \phi \cdot 1 = id $ 。
然后直接转化:
& \sum_{T} ( ( \sum w_{e_i} ) * gcd( w_{e_i} ) ) \\
= & \sum_{T} ( ( \sum w_{e_i} ) * \sum_{d|gcd( w_{e_i} )} \phi(d) ) \\
= & \sum_{d} \phi(d) \sum_{T:d|gcd( w_{e_i} )} ( \sum w_{e_i} )
\end{aligned}
\]
然后对于求出边权和,简单的想法是对于每条边求有多少含这条边的树。
这时就可以想到矩阵树定理了。但怎么对于每个边求呢?
简单思考发现矩阵元素变成 $ (a+bx) $ 的形式就可以解决。
一条边加的元素是 $ (1+wx) $ ,答案就是求得结果的一次项系数。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long lint;
template<typename TP>inline void read(TP &tar)
{
TP ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){ret=ret*10+(ch-'0');ch=getchar();}
tar=ret*f;
}
namespace RKK
{
const int N=40,M=500;
const int mo=998244353;
int add(const int &a,const int &b){return a+b>=mo?a+b-mo:a+b;}
void doadd(int &a,const int &b){if((a+=b)>=mo) a-=mo;}
int fpow(int a,int p){int ret=1;while(p){if(p&1)ret=1ll*ret*a%mo;a=1ll*a*a%mo,p>>=1;}return ret;}
int pr[160011],pc,phi[160011];bool npr[160011];
void sieve()
{
phi[1]=1;for(int i=2;i<=160000;i++)
{
if(!npr[i]) pr[++pc]=i,phi[i]=i-1;
for(int j=1;j<=pc&&i*pr[j]<=160000;j++)
{
npr[i*pr[j]]=1;
if(i%pr[j]==0){phi[i*pr[j]]=phi[i]*pr[j];break;}
else phi[i*pr[j]]=phi[i]*(pr[j]-1);
}
}
}
int n,m,ans,ex[M],ey[M],ew[M];
struct pat
{
int x,y;
pat(const int &x=0,const int &y=0):x(x),y(y){}
pat operator+(const pat &p)const{return pat(add(x,p.x),add(y,p.y));}
pat operator-(const pat &p)const{return pat(add(x,mo-p.x),add(y,mo-p.y));}
pat operator*(const pat &p)const{return pat(1ll*x*p.x%mo,(1ll*x*p.y+1ll*p.x*y)%mo);}
pat operator/(const pat &p)const
{
int iv=fpow(p.x,mo-2);
return pat(1ll*x*iv%mo,1ll*add(1ll*y*p.x%mo,mo-1ll*x*p.y%mo)*iv%mo*iv%mo);
}
};
pat a[N][N];
pat mtree()
{
pat ret=pat(1,0);bool rev=0;
for(int l=1,e;l<n;l++)
{
for(e=l;e<n;e++)if(a[e][l].x) break;if(e==n) return pat(0,0);
if(e!=l){rev^=1;for(int j=1;j<n;j++) swap(a[l][j],a[e][j]);}
pat k=pat(1,0)/a[l][l];
for(int i=l+1;i<n;i++)
{
pat g=k*a[i][l];
for(int j=l;j<n;j++) a[i][j]=a[i][j]-g*a[l][j];
}
ret=ret*a[l][l];
}
if(rev) ret=pat(0,0)-ret;return ret;
}
int getans(int p)
{
memset(a,0,sizeof(a));
for(int i=1;i<=m;i++)if(ew[i]%p==0)
{
a[ex[i]][ey[i]]=a[ex[i]][ey[i]]-pat(1,ew[i]);
a[ey[i]][ex[i]]=a[ey[i]][ex[i]]-pat(1,ew[i]);
a[ex[i]][ex[i]]=a[ex[i]][ex[i]]+pat(1,ew[i]);
a[ey[i]][ey[i]]=a[ey[i]][ey[i]]+pat(1,ew[i]);
}
return mtree().y;
}
int ct[160011];
int main()
{
sieve();read(n),read(m);
for(int i=1;i<=m;i++)
{
read(ex[i]),read(ey[i]),read(ew[i]);
for(int j=1;j*j<=ew[i];j++)if(ew[i]%j==0){ct[j]++;if(ew[i]/j!=j) ct[ew[i]/j]++;}
}
for(int i=1;i<=160000;i++)if(ct[i]>=n-1) ans=(ans+1ll*phi[i]*getans(i))%mo;
printf("%d\n",ans);
return 0;
}
}
int main(){return RKK::main();}
luoguP6624 [省选联考 2020 A 卷] 作业题(莫比乌斯反演,矩阵树定理)的更多相关文章
- 洛谷 P6624 - [省选联考 2020 A 卷] 作业题(矩阵树定理+简单数论)
题面传送门 u1s1 这种题目还是相当套路的罢 首先看到 \(\gcd\) 可以套路地往数论方向想,我们记 \(f_i\) 为满足边权的 \(\gcd\) 为 \(i\) 的倍数的所有生成树的权值之和 ...
- [省选联考 2020 A 卷] 组合数问题
题意 [省选联考 2020 A 卷] 组合数问题 想法 自己在多项式和数论方面还是太差了,最近写这些题都没多少思路,看完题解才会 首先有这两个柿子 \(k*\dbinom{n}{k} = n*\dbi ...
- luoguP6623 [省选联考 2020 A 卷] 树(trie树)
luoguP6623 [省选联考 2020 A 卷] 树(trie树) Luogu 题外话: ...想不出来啥好说的了. 我认识的人基本都切这道题了. 就我只会10分暴力. 我是傻逼. 题解时间 先不 ...
- luoguP6620 [省选联考 2020 A 卷] 组合数问题(斯特林数)
luoguP6620 [省选联考 2020 A 卷] 组合数问题(斯特林数) Luogu 题外话: LN切这题的人比切T1的多. 我都想到了组合意义乱搞也想到可能用斯特林数为啥还是没做出来... 我怕 ...
- 洛谷P6623——[省选联考 2020 A 卷] 树
传送门:QAQQAQ 题意:自己看 思路:正解应该是线段树/trie树合并? 但是本蒟蒻啥也不会,就用了树上二次差分 (思路来源于https://www.luogu.com.cn/blog/dengy ...
- P6628-[省选联考 2020 B 卷] 丁香之路【欧拉回路,最小生成树】
正题 题目链接:https://www.luogu.com.cn/problem/P6628 题目大意 给出\(n\)个点的一张完全无向图,\(i\sim j\)的边权是\(|i-j|\). 然后给出 ...
- [题解] LOJ 3300 洛谷 P6620 [省选联考 2020 A 卷] 组合数问题 数学,第二类斯特林数,下降幂
题目 题目里要求的是: \[\sum_{k=0}^n f(k) \times X^k \times \binom nk \] 这里面出现了给定的多项式,还有组合数,这种题目的套路就是先把给定的普通多项 ...
- 题解 P6622 [省选联考 2020 A/B 卷] 信号传递
洛谷 P6622 [省选联考 2020 A/B 卷] 信号传递 题解 某次模拟赛的T2,考场上懒得想正解 (其实是不会QAQ), 打了个暴力就骗了\(30pts\) 就火速溜了,参考了一下某位强者的题 ...
- luoguP6622 [省选联考 2020 A/B 卷] 信号传递(状压dp)
luoguP6622 [省选联考 2020 A/B 卷] 信号传递(状压dp) Luogu 题外话: 我可能是傻逼, 但不管我是不是傻逼, 我永远单挑出题人. 题解时间 看数据范围可以确定状压dp. ...
随机推荐
- opencv笔记--SURF
SURF(Speeded-Up Robust Features) 是对 SIFT 得改进,相对于 SIFT,SURF 利用积分图像与盒函数模拟 DoG,提升了计算速度:同时,使用了一种不用于 SIFT ...
- Node.JS学习——学习笔记
Node.JS--学习笔记 2020年02月23日11:52:01 我打算自学NodeJS-通过阅读NodeJS官网来完成. https://nodejs.org/dist/latest-v13.x/ ...
- Python+selenium自动循环发邮件
Python源代码如下: # coding=utf-8 from selenium import webdriver from time import sleep from random import ...
- DotNet Dictionary 实现简介
一:前言 本来笔者对DotNet的Hashtable及Dictionary认识一直集中在使用上,一个直接用object 一个可以用泛型,以前也只大概看过Hashtable的实现.最近查MSDN时发现有 ...
- [题解]第十一届北航程序设计竞赛预赛——D.最大公约数
题目描述 给一个长度为n(1<=n<=100000)的正整数列,分成尽量多的非空段,使得每一段的最大公约数相等.一个数的最大公约数是它本身. 解题思路 要求每一段子列的gcd相等,不妨设为 ...
- 论文解读(Geom-GCN)《Geom-GCN: Geometric Graph Convolutional Networks》
Paper Information Title:Geom-GCN: Geometric Graph Convolutional NetworksAuthors:Hongbin Pei, Bingzhe ...
- 微服务从代码到k8s部署应有尽有系列(九、事务精讲)
我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...
- killall 、kill 、pkill 命令区别
转至:https://zhuanlan.zhihu.com/p/87904563 killall 命令 Linux系统中的killall命令用于杀死指定名字的进程(kill processes by ...
- java 读取xlsx文件
public class ReadExcel { public static void main(String[] args) { Workbook wb = null; Sheet sheet = ...
- 五、ES6之对象
一.对象和属性和方法 JavaScript中对象: var person={name:"Jack",age:20}; 或: var name = "jack"; ...