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)\) 为所有能通过若干次"替换 \( ...
随机推荐
- linux 三剑客(持续更新)排版后续再说,边学边记笔记
切记:seq命令用于产生从某个数到另外一个数之间的所有整数.sed才是处理文本的命令 在遇到扩展符号时,需要添加特定参数,| () +[] 为扩展符号时,必须添加参数 egrep/grep -E s ...
- Centos7 文件修改详情
Centos常规修改信息 记录文件在系统中的意义 /etc/locale.conf ---修改字符集文件 /etc/profile ---修改环境变量
- Go语言系列之并发编程
Go语言中的并发编程 并发与并行 并发:同一时间段内执行多个任务(宏观上并行,微观上并发). 并行:同一时刻执行多个任务(宏观和微观都是并行). Go语言的并发通过goroutine实现.gorout ...
- element ui 动态菜单解决方案集锦
1.<分享一个VUE Element-UI 的多级菜单动态渲染的组件> 2.<饿了么组件库,element-ui开发精美的后台管理系统系列之(一)开发伸缩菜单> 3.<V ...
- js对象方法
Number对象方法 toFixed() 方法 toFixed()方法返回的是具有指定位数小数的数字的字符串表示.例如: var oNumberObject = new Number(68); ale ...
- Springboot整合Mybatis,连接多个数据库(Mysql+Oracle)
maven依赖,需要注意的是mysql使用的版本 1 <dependencies> 2 <dependency> 3 <groupId>com.oracle.dat ...
- HDU 2099 整除的尾数(枚举 & 暴搜)
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2099 思路分析:这道题的解法可以说是相当暴力了,但也有一些小坑,以下几点萌新们值得留意一下: 1. 仔 ...
- Electron+Vue开发跨平台桌面应用
Electron+Vue开发跨平台桌面应用 xiangzhihong发布于 2019-12-23 虽然B/S是目前开发的主流,但是C/S仍然有很大的市场需求.受限于浏览器的沙盒限制,网页应用无法满足某 ...
- Matlab R2019b安装中的问题
1.licens文件以及dll文件的放置 MATLAB的安装镜像文件放置在D:\MATLAB,我们MATLAB安装在D:\MATLAB2019B,在激活过程中,我们需要破解文件夹中的license_s ...
- ArrayList实现类
特点 数组结构实现,查询快,增删慢 运行效率高,线程不安全 可重复 常用方法 Modifier and Type Method and Description boolean add(E e) 将指定 ...