传送门

由于是边权三进制不进位的相加,那么可以考虑每一位的贡献

对于每一位,生成树的边权相当于是做模 \(3\) 意义下的加法

考虑最后每一种边权的生成树个数,这个可以直接用生成函数,在矩阵树求解的时候做一遍这个生成函数的模 \(3\) 意义下的循环卷积求出系数即可

暴力多项式运算不可取

考虑选取 \(3\) 个数字 \(x_i\),使得 \(x_i^3\equiv1(mod~10^9+7)\)

即找出 \(3\) 次单位复数根 \(\omega_3^0,\omega_3^1,\omega_3^2\)

这个直接带入三角表示法即可得到

把这些东西带入,矩阵树定理求出点值,最后手动 \(DFT^{-1}\) 即可

# include <bits/stdc++.h>
using namespace std;
typedef long long ll; const int mod(1e9 + 7);
const int inv2((mod + 1) >> 1);
const int inv3((mod + 1) / 3);
const int rt3(82062379); inline int Pow(ll x, int y) {
ll ret = 1;
for (; y; y >>= 1, x = x * x % mod)
if (y & 1) ret = ret * x % mod;
return ret;
} inline void Inc(int &x, int y) {
x = x + y >= mod ? x + y - mod : x + y;
} inline void Dec(int &x, int y) {
x = x - y < 0 ? x - y + mod : x - y;
} inline int Add(int x, int y) {
return x + y >= mod ? x + y - mod : x + y;
} inline int Sub(int x, int y) {
return x - y < 0 ? x - y + mod : x - y;
} struct Complex {
int a, b; inline Complex(int _a = 0, int _b = 0) {
a = _a, b = _b;
} inline Complex operator +(Complex y) const {
return Complex(Add(a, y.a), Add(b, y.b));
} inline Complex operator -(Complex y) const {
return Complex(Sub(a, y.a), Sub(b, y.b));
} inline Complex operator *(Complex y) const {
return Complex(Sub((ll)a * y.a % mod, (ll)b * y.b % mod), Add((ll)a * y.b % mod, (ll)b * y.a % mod));
} inline Complex operator *(int y) const {
return Complex((ll)a * y % mod, (ll)b * y % mod);
} inline Complex operator /(int y) const {
int inv = Pow(y, mod - 2);
return Complex((ll)a * inv % mod, (ll)b * inv % mod);
} inline Complex operator /(Complex y) const {
return Complex(a, b) * Complex(y.a, mod - y.b) / Add((ll)y.a * y.a % mod, (ll)y.b * y.b % mod);
}
} a[105][105], coef[3], inv, w[3], invw[3]; int n, m, eu[105 * 105], ev[105 * 105], ec[105 * 105], bin[20]; inline Complex Det() {
int i, j, k;
Complex ret = Complex(1, 0);
for (i = 1; i < n; ++i) {
for (j = i; j < n; ++j)
if (a[j][i].a || a[j][i].b) {
if (i == j) break;
swap(a[i], a[j]), ret = ret * (mod - 1);
break;
}
for (j = i + 1; j < n; ++j) {
inv = a[j][i] / a[i][i];
for (k = i; k < n; ++k) a[j][k] = a[j][k] - inv * a[i][k];
}
ret = ret * a[i][i];
}
return ret;
} inline void IDFT(Complex *p) {
int i;
Complex tmp[3];
tmp[0] = p[0], tmp[1] = p[1], tmp[2] = p[2];
p[0] = tmp[0] + tmp[1] + tmp[2];
p[1] = tmp[0] + tmp[1] * invw[1] + tmp[2] * invw[2];
p[2] = tmp[0] + tmp[1] * invw[2] + tmp[2] * invw[1];
for (i = 0; i < 3; ++i) p[i] = p[i] * inv3;
} inline int Calc(int p) {
int i, j, k;
Complex w0, w1, w2, c;
for (i = 0; i < 3; ++i) {
memset(a, 0, sizeof(a));
w0 = Complex(1, 0), w1 = w[i], w2 = w[(i + i) % 3];
for (j = 1; j <= m; ++j) {
k = ec[j] / bin[p] % 3;
c = (k == 1 ? w1 : (k == 2 ? w2 : w0));
a[eu[j]][eu[j]] = a[eu[j]][eu[j]] + c;
a[ev[j]][ev[j]] = a[ev[j]][ev[j]] + c;
a[eu[j]][ev[j]] = a[eu[j]][ev[j]] - c;
a[ev[j]][eu[j]] = a[ev[j]][eu[j]] - c;
}
coef[i] = Det();
}
IDFT(coef);
return (ll)Add(coef[1].a, Add(coef[2].a, coef[2].a)) * bin[p] % mod;
} int main() {
int i, ans = 0;
scanf("%d%d", &n, &m);
w[0] = Complex(1, 0), w[1] = Complex(mod - inv2, (ll)rt3 * inv2 % mod);
w[2] = Complex(mod - inv2, mod - (ll)rt3 * inv2 % mod);
invw[0] = Complex(1, 0) / w[0], invw[1] = Complex(1, 0) / w[1], invw[2] = Complex(1, 0) / w[2];
for (i = 1; i <= m; ++i) scanf("%d%d%d", &eu[i], &ev[i], &ec[i]);
for (bin[0] = i = 1; i <= 10; ++i) bin[i] = bin[i - 1] * 3;
for (i = 0; i <= 10; ++i) Inc(ans, Calc(i));
printf("%d\n", ans);
return 0;
}

LOJ#6271. 「长乐集训 2017 Day10」生成树求和 加强版的更多相关文章

  1. loj6271 「长乐集训 2017 Day10」生成树求和 加强版(矩阵树定理,循环卷积)

    loj6271 「长乐集训 2017 Day10」生成树求和 加强版(矩阵树定理,循环卷积) loj 题解时间 首先想到先分开三进制下每一位,然后每一位分别求结果为0,1,2的树的个数. 然后考虑矩阵 ...

  2. loj6271「长乐集训 2017 Day10」生成树求和 加强版

    又是一个矩阵树套多项式的好题. 这里我们可以对每一位单独做矩阵树,但是矩阵树求的是边权积的和,而这里我们是要求加法,于是我们i将加法转化为多项式的乘法,其实这里相当于一个生成函数?之后如果我们暴力做的 ...

  3. 「长乐集训 2017 Day10」划分序列 (二分 dp)

    「长乐集训 2017 Day10」划分序列 题目描述 给定一个长度为 n nn 的序列 Ai A_iA​i​​,现在要求把这个序列分成恰好 K KK 段,(每一段是一个连续子序列,且每个元素恰好属于一 ...

  4. 「长乐集训 2017 Day1」区间 线段树

    题目 对于两个区间\((a,b),(c,d)\),若\(c < a < d\)或\(c < b < d\)则可以从\((a,b)\)走到\((c,d)\)去,现在有以下两种操作 ...

  5. 「长乐集训 2017 Day8」修路 (斯坦纳树)

    题目描述 村子间的小路年久失修,为了保障村子之间的往来,AAA君决定带领大家修路. 村子可以看做是一个边带权的无向图GGG, GGG 由 nnn 个点与 mmm 条边组成,图中的点从 1∼n1 \si ...

  6. Loj #2331. 「清华集训 2017」某位歌姬的故事

    Loj #2331. 「清华集训 2017」某位歌姬的故事 IA 是一名会唱歌的女孩子. IOI2018 就要来了,IA 决定给参赛选手们写一首歌,以表达美好的祝愿.这首歌一共有 \(n\) 个音符, ...

  7. Loj #2324. 「清华集训 2017」小 Y 和二叉树

    Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...

  8. Loj #2321. 「清华集训 2017」无限之环

    Loj #2321. 「清华集训 2017」无限之环 曾经有一款流行的游戏,叫做 *Infinity Loop***,先来简单的介绍一下这个游戏: 游戏在一个 \(n \times m\) 的网格状棋 ...

  9. Loj 2320.「清华集训 2017」生成树计数

    Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...

随机推荐

  1. 使用python进行短信轰炸

    本文作者:i春秋作家——Hacker1ee 大家好,我是1ee(因为在作家群,就不加Hacker这个前缀了,怕被大佬打..) 刚加入i春秋作家组希望大家多多关照,也欢迎大家找我交流 今天我来讲讲我最近 ...

  2. 下载Centos7 64位镜像

    下载Centos7 64位镜像 1.打开Centos官网 打开Centos官方网站地址:https://www.centos.org/,点击Get CentOS Now 2.点击Minimal ISO ...

  3. Postman+Newman+Jenkins 详细教程

    详细步骤点击: https://note.youdao.com/web/#/file/WEBda9492a77807d8050b40f8315bf6554a/note/WEBde553e6dff6ff ...

  4. Requests库入门实例

    爬虫入门5个实例 实例1:京东商品页面的爬取 import requests def getHTMLText(url): try: r = requests.get(url,timeout = 30) ...

  5. Java Web入门学习(四)Eclipse与Maven、Tomcat整合配置 (重整版并解决问题)

    Java Web学习(四)Eclipse与Maven整合配置 (重整版) 一.准备工作 1.Tomcat 8.5.15 2.Maven3.5 3.Eclipse Neon.3 Release (4.6 ...

  6. 按照Right-BICEP要求对实验二进行测试

    我的代码实现的功能很简单,在最基本的功能上,包括有无括号(0/1),有无负数(0/1),有无乘除法(0/1)验证程序的正确性,测试用例为8个,2^3个,也就覆盖了所有的代码路径. 测试计划: 基本功能 ...

  7. Android Studio SVN的使用

    一 SVN的配置 这篇文章使用的Android studio版本为1.4 RC3. 我选择的是TortoiseSVN,版本为1.8,不要选择1.9版本(目前的最新版),因为如果你安装的是1.9版本当你 ...

  8. 全连接层(FC)与全局平均池化层(GAP)

    在卷积神经网络的最后,往往会出现一两层全连接层,全连接一般会把卷积输出的二维特征图转化成一维的一个向量,全连接层的每一个节点都与上一层每个节点连接,是把前一层的输出特征都综合起来,所以该层的权值参数是 ...

  9. java.lang.NoSuchMethodError: org.json.JSONArray.iterator()Ljava/util/Iterator 阿里云短信

    请尝试使用 <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk ...

  10. json 只能用 for-in 遍历

    [JS] var json1 = { 'name' : 'yy' , 'age' : 11 , 'fun' : '前端开发' }; for( var attr in json1 ) { alert( ...