题目传送门

  戳我来传送

题目大意

  给定一个图,问它的所有生成树的边权的最大公约数之和。

  可以考虑计算边权的最大公约数为$i$的生成树的个数$f(i)$,最后累加答案。

  然后考虑这样的生成树的个数怎么求,根据某个经典套路,我们可以容斥。

  因为可以求出边权的最大公约数为$i$的倍数的生成树的个数$F(i)$,所以减去它的倍数的$f$就是$f(i)$了。

  但是这么做会T掉。

  可以用$O(W\log W)$的时间内预处理出为边权$i$的倍数的边数有多少条。然后高消前判断一下边数是否大于等于$n - 1$。

  具体有关时间复杂度的证明可以在洛谷的题解中找到,这里就不给出了。

Code

 /**
* luogu
* Problem#3790
* Accepted
* Time: 6016ms
* Memory: 9402k
*/
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef bool boolean;
#define ll long long const int N = , M = 1e9 + ; void exgcd(int a, int b, int& d, int& x, int& y) {
if(!b)
d = a, x = , y = ;
else {
exgcd(b, a % b, d, y, x);
y -= (a / b) * x;
}
} int inv(int a, int n) {
int d, x, y;
exgcd(a, n, d, x, y);
return (x < ) ? (x + n) : (x);
} typedef class Matrix {
public:
int a[N][N]; void reset() {
memset(a, , sizeof(a));
} int det(int n) {
int pro = ;
for (int i = , e; i <= n; i++) {
e = ;
for (int j = i; j <= n && !e; j++)
if (a[j][i])
e = j;
if (e == ) return ;
if (e != i)
for (int j = ; j <= n; j++)
swap(a[e][j], a[i][j]);
for (int j = , x, y; j <= n; j++) {
if (j == i) continue;
x = a[i][i], y = a[j][i], pro = pro * 1ll * x % M;
for (int k = ; k <= n; k++) {
a[j][k] = (a[j][k] * 1ll * x - a[i][k] * 1ll * y) % M;
if (a[j][k] < ) a[j][k] += M;
} }
}
int rt = inv(pro, M);
for (int i = ; i <= n; i++)
rt = rt * 1ll * a[i][i] % M;
return rt;
}
}Matrix; typedef class Edge {
public:
int u, v, w;
}Edge; const int Val = 1e6 + ; int n, m;
Edge* es;
Matrix a;
int ce[Val], f[Val]; inline void init() {
scanf("%d%d", &n, &m);
es = new Edge[(m + )];
for (int i = ; i <= m; i++)
scanf("%d%d%d", &es[i].u, &es[i].v, &es[i].w), ce[es[i].w]++;
} int calc(int g) {
if (ce[g] < n - ) return ;
a.reset();
for (int i = , u, v; i <= m; i++)
if (!(es[i].w % g)) {
u = es[i].u - , v = es[i].v - ;
a.a[u][u]++, a.a[v][v]++;
a.a[u][v]--, a.a[v][u]--;
if (a.a[u][v] < ) a.a[u][v] += M;
if (a.a[v][u] < ) a.a[v][u] += M;
}
int rt = a.det(n - );
// cerr << rt << endl;
return rt;
} int res = ;
inline void solve() {
for (int i = ; i < Val; i++)
for (int j = (i << ); j < Val; j += i)
ce[i] += ce[j];
for (int i = Val - ; i; i--) {
f[i] = calc(i);
for (int j = (i << ); j < Val; j += i) {
f[i] -= f[j];
if (f[i] < )
f[i] += M;
}
res = (res + f[i] * 1ll * i) % M;
}
printf("%d", res);
} int main() {
init();
solve();
return ;
}

luogu 3790 文艺数学题 - 矩阵树定理 - 容斥原理的更多相关文章

  1. Luogu P4336 [SHOI2016]黑暗前的幻想乡 矩阵树定理+容斥原理

    真是菜到爆炸....容斥写反(反正第一次写qwq) 题意:$n-1$个公司,每个公司可以连一些边,求每个边让不同公司连的生成树方案数. 矩阵树定理+容斥原理(注意到$n$不是很大) 枚举公司参与与否的 ...

  2. 【bzoj4596】[Shoi2016]黑暗前的幻想乡 容斥原理+矩阵树定理

    题目描述 给出 $n$ 个点和 $n-1$ 种颜色,每种颜色有若干条边.求这张图多少棵每种颜色的边都出现过的生成树,答案对 $10^9+7$ 取模. 输入 第一行包含一个正整数 N(N<=17) ...

  3. bzoj 4596: [Shoi2016]黑暗前的幻想乡【容斥原理+矩阵树定理】

    真是简单粗暴 把矩阵树定理的运算当成黑箱好了反正我不会 这样我们就可以在O(n^3)的时间内算出一个无向图的生成树个数了 然后题目要求每个工程队选一条路,这里可以考虑容斥原理:全选的方案数-不选工程队 ...

  4. BZOJ 4766: 文艺计算姬 [矩阵树定理 快速乘]

    传送门 题意: 给定一个一边点数为n,另一边点数为m,共有n*m条边的带标号完全二分图$K_{n,m}$ 求生成树个数 1 <= n,m,p <= 10^18 显然不能暴力上矩阵树定理 看 ...

  5. 【BZOJ 4596】 4596: [Shoi2016]黑暗前的幻想乡 (容斥原理+矩阵树定理)

    4596: [Shoi2016]黑暗前的幻想乡 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 324  Solved: 187 Description ...

  6. 【Luogu】P3317重建(高斯消元+矩阵树定理)

    题目链接 因为这个专门跑去学了矩阵树定理和高斯消元qwq 不过不是很懂.所以这里只放题解 玫葵之蝶的题解 某未知dalao的矩阵树定理 代码 #include<cstdio> #inclu ...

  7. 【BZOJ4596】【Luogu P4336】 [SHOI2016]黑暗前的幻想乡 矩阵树定理,容斥

    同样是矩阵树定理的裸题.但是要解决它需要能够想到容斥才可以. \(20\)以内的数据范围一定要试试容斥的想法. #include <bits/stdc++.h> using namespa ...

  8. 【BZOJ4596】[Shoi2016]黑暗前的幻想乡 容斥+矩阵树定理

    [BZOJ4596][Shoi2016]黑暗前的幻想乡 Description 幽香上台以后,第一项措施就是要修建幻想乡的公路.幻想乡有 N 个城市,之间原来没有任何路.幽香向选民承诺要减税,所以她打 ...

  9. 洛谷 P4336 黑暗前的幻想乡 —— 容斥+矩阵树定理

    题目:https://www.luogu.org/problemnew/show/P4336 当作考试题了,然而没想出来,呵呵. 其实不是二分图完美匹配方案数,而是矩阵树定理+容斥... 就是先放上所 ...

随机推荐

  1. iOS Xcode 用 GitHub 托管项目

    直接在xcode里用Github教程:http://jingyan.baidu.com/article/ab0b5630936ab6c15afa7d1c.html 经过本人尝试之后,发现,使用官网的客 ...

  2. 用int还是用Integer?

    昨天例行code review时大家有讨论到int和Integer的比较和使用. 这里做个整理,发表一下个人的看法.   [int和Integer的区别] int是java提供的8种原始类型之一,ja ...

  3. VS2010和选中代码相同的代码的颜色设置,修改高亮颜色

    使用Visual Studio 2010, 发现很难看清非活动的选中代码,研究了下,发现以下方法可以设置: 1. 菜单:工具  -> 选项  ->环境  ->字体和颜色 2. 在右边 ...

  4. TP图片上传

    //控制器文件 public function index(){ if(!empty($_POST)){ $file = $_FILES["file"]; if(!isset($f ...

  5. java中垃圾回收机制中的引用计数法和可达性分析法(最详细)

    首先,我这是抄写过来的,写得真的很好很好,是我看过关于GC方面讲解最清楚明白的一篇.原文地址是:https://www.zhihu.com/question/21539353

  6. scrapy 参考教程及安装

    scrapy 参考教程及安装环境: win7/10 64bit, python 3.6.x教程: http://python.jobbole.com/86405/安装过程0. 预先安装 VC14 64 ...

  7. Some Useful Resources for the Future Usage

    并发编程 http://ifeve.com/ 美国各州 http://114.xixik.com/usa-stats/ 美国各州邮编zip code -> https://www.douban. ...

  8. UVa-116 Unidirectional TSP 单向旅行商

    题目 https://vjudge.net/problem/uva-116 分析 设d[i][j]为从(i,j)到最后一列的最小开销,则d[i][j]=a[i][j]+max(d[i+1][j+1], ...

  9. SNMP 安装及使用

    一.SNMP的安装 1.安装 snmp服务,python扩展等 参考:http://lihuipeng.blog.51cto.com/3064864/915965 [root@localhost] y ...

  10. windows8安装msi或exe软件提示2503错误的解决办法

    windows8以后的版本安装msi软件(比如nodejs.msi.Git.msi.python.msi.T ortoiseSVN.msi)的时候老师出现2503.2502的错误,究其原因还是系统权限 ...