Solution -「51nod 1868」彩色树
\(\mathcal{Description}\)
给定一棵 \(n\) 个结点的树,每个结点有一种颜色。记 \(g(u,v)\) 表示 \(u\) 到 \(v\) 简单路径上的颜色种数,求
\]
其中 \(\{p_n\}\) 表示 \(1\sim n\) 的排列。
\(n\le10^5\),答案对 \((10^9+7)\) 取模。
\(\mathcal{Solution}\)
常见但不熟悉的 trick 题。(
不难想到分颜色计算贡献。而“路径上至少出现某种颜色”不好计算,考虑反向计算“路径上不包含某种颜色”的路径条数。
对于颜色 \(c\),删除所有颜色为 \(c\) 的结点,记得到联通块的大小为 \(s_{1..m}\),那么上述路径数量为 \(\sum_{i=1}^m\frac{s_i(s_i-1)}2\)。称一个联通块深度最小的结点为其顶点,我们尝试在顶点处对这个联通块计数。可以看出,要不顶点是根,要不顶点父亲的颜色为 \(c\)。前者单独考虑,后者仅需用顶点子树大小减去顶点子树内以 \(c\) 颜色的结点作为根的子树大小。所以用前后作差的 trick:DFS 进入子树前,记录目前以 \(c\) 色点为根的子树大小和 \(s\),退出子树后,得到当前以 \(c\) 色点为根的子树大小和 \(t\)。那么该联通块的大小即为 \(t-s\)。
所以 DFS 一遍就可以啦。复杂度 \(\mathcal O(n)\)。
\(\mathcal{Code}\)
/* Clearink */
#include <cstdio>
#include <vector>
#include <algorithm>
#define rep( i, l, r ) for ( int i = l, repEnd##i = r; i <= repEnd##i; ++i )
#define per( i, r, l ) for ( int i = r, repEnd##i = l; i >= repEnd##i; --i )
inline int rint () {
int x = 0, f = 1; char s = getchar ();
for ( ; s < '0' || '9' < s; s = getchar () ) f = s == '-' ? -f : f;
for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
return x * f;
}
const int MAXN = 1e5, MOD = 1e9 + 7;
int n, ecnt, ans, clr[MAXN + 5], head[MAXN + 5], siz[MAXN + 5], sum[MAXN + 5];
struct Edge { int to, nxt; } graph[MAXN * 2 + 5];
inline int mul ( const long long a, const int b ) { return a * b % MOD; }
inline int sub ( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
inline int add ( int a, const int b ) { return ( a += b ) < MOD ? a : a - MOD; }
inline void link ( const int s, const int t ) {
graph[++ecnt] = { t, head[s] };
head[s] = ecnt;
}
inline int count ( const int s ) { return ( s * ( s - 1ll ) >> 1 ) % MOD; }
inline void dfs ( const int u, const int fa ) {
siz[u] = 1, ++sum[clr[u]];
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa ) {
int s = sum[clr[u]];
dfs ( v, u ), siz[u] += siz[v];
int t = sum[clr[u]], dlt = t - s;
ans = add ( ans, count ( siz[v] - dlt ) );
sum[clr[u]] += siz[v] - dlt;
}
}
}
int main () {
n = rint ();
rep ( i, 1, n ) clr[i] = rint ();
for ( int i = 1, u, v; i < n; ++i ) {
u = rint (), v = rint ();
link ( u, v ), link ( v, u );
}
dfs ( 1, 0 );
rep ( c, 1, n ) {
if ( c ^ clr[1] ) {
ans = add ( ans, count ( n - sum[c] ) );
}
}
ans = sub ( mul ( n, count ( n ) ), ans );
int fct = 1;
rep ( i, 1, n - 2 ) fct = mul ( fct, i );
printf ( "%d", mul ( ans, mul ( 2, mul ( n - 1, fct ) ) ) );
return 0;
}
Solution -「51nod 1868」彩色树的更多相关文章
- Solution -「51nod 1514」美妙的序列
\(\mathcal{Description}\) Link. 称排列 \(\{p_n\}\) 美妙,当且仅当 \((\forall i\in[1,n))(\max_{j\in[1,i]}\{ ...
- Solution -「51nod 1355」斐波那契的最小公倍数
\(\mathcal{Description}\) Link. 令 \(f\) 为 \(\text{Fibonacci}\) 数列,给定 \(\{a_n\}\),求: \[\operatorn ...
- Solution -「51nod 1584」加权约数和
\(\mathcal{Description}\) Link. 令 \(\sigma(n)\) 为 \(n\) 的约数之和.求: \[\sum_{i=1}^n\sum_{j=1}^n\max\ ...
- 「WC 2019」数树
「WC 2019」数树 一道涨姿势的EGF好题,官方题解我并没有完全看懂,尝试用指数型生成函数和组合意义的角度推了一波.考场上只得了 44 分也暴露了我在数数的一些基本套路上的不足,后面的 \(\ex ...
- [Luogu 3701] 「伪模板」主席树
[Luogu 3701] 「伪模板」主席树 这是一道网络流,不是主席树,不是什么数据结构,而是网络流. 题目背景及描述都非常的暴力,以至于 Capella 在做此题的过程中不禁感到生命流逝. S 向 ...
- 【题解】#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT)
[题解]#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT) 之前做这道题不理解,有一点走火入魔了,甚至想要一本近世代数来看,然后通过人类智慧思考后发现, ...
- Solution -「ARC 104E」Random LIS
\(\mathcal{Description}\) Link. 给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...
- Solution -「LOJ #6029」「雅礼集训 2017」市场
\(\mathcal{Description}\) Link. 维护序列 \(\lang a_n\rang\),支持 \(q\) 次如下操作: 区间加法: 区间下取整除法: 区间求最小值: 区 ...
- Solution -「NOI 2020」「洛谷 P6776」超现实树
\(\mathcal{Description}\) Link. 对于非空二叉树 \(T\),定义 \(\operatorname{grow}(T)\) 为所有能通过若干次"替换 \( ...
随机推荐
- wordpress搭建网站更改域名后打开网页排版显示错乱解决办法
发生的原因: 我本来已经搭建好了网站,也测试了没问题.后来更改了网站的域名,出现了这种情况. 解决办法: 需要修改数据库的options表里面的 siteurl 和 home 这两个表的内容为最新的域 ...
- 在 CentOS 7 上安装和配置 Puppet
1 准备 2台 centos7 (master/server:192.168.1.103 agent/client:192.168.1.106) 分别添加puppet自定义仓库 https://yum ...
- SYCOJ570传纸条
题目-传纸条 (shiyancang.cn) 算法(线性DP) O(n3)O(n3)首先考虑路径有交集该如何处理.可以发现交集中的格子一定在每条路径的相同步数处.因此可以让两个人同时从起点出发,每次同 ...
- test_4 实现一个统计函数运行时间
1.datetime显示当前时间 import datetimeimport timedef func(): t = datetime.datetime.now() print t print &qu ...
- 开启mysql外部访问(root外连)
MySQL外部访问 mysql 默认是禁止远程连接的,你在安装mysql的系统行运行mysql -u root -p 后进入mysql 输入如下: mysql>use mysql; mysql& ...
- linux开放端口关闭防火墙
linux开放端口关闭防火墙 systemctl status firewalld查看当前防火墙状态. 开启防火墙 systemctl start firewalld开放指定端口 ...
- day4 对偶数、偶数位的操作
1.函数fun()的功能:从低位开始取出整形变量s中偶数位上的数,依次构成一个新数放在t中.高位仍在高位. 效果理想:但是经测试的时候出现了错误 输入987654321时,打印出来的却是18681.经 ...
- 【机器学习】svm
机器学习算法--SVM 目录 机器学习算法--SVM 1. 背景 2. SVM推导 2.1 几何间隔和函数间隔 2.2 SVM原问题 2.3 SVM对偶问题 2.4 SMO算法 2.4.1 更新公式 ...
- Allure测试报告完整学习笔记
目录 简介 安装Allure Allure测试报告的结构 Java TestNG集成Allure Report Python Pytest集成Allure Report 简介 假如你想让测试报告变得漂 ...
- 『无为则无心』Python函数 — 40、Python自定义异常
目录 1.使用 raise 语句来抛出异常 (1)抛出异常类 (2)抛出异常类的实例 2.自定义异常类 (1)简单实现 (2)完整实现 在Python中,抛出自定义异常的语法为 raise 异常类对象 ...