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)\) 为所有能通过若干次"替换 \( ...
随机推荐
- koa路由接口
const router = require('koa-router')() //返回一个页面 router.get('/', async (ctx, next) => { global.con ...
- Java带包结构调用命令行运行编译
原文: https://www.toutiao.com/i6491809562037846542/ 带包结构调用命令行运行编译. 记事本编写两个简单的类 文件结构目录 启动DOS,进入文件所在目录 分 ...
- vue爬坑之路(axios 封装篇)
第一步还是先下载axios cnpm install axios -S第二步建立一个htttp.js import axios from 'axios'; import { Message } fro ...
- STC8H开发(四): FwLib_STC8 封装库的介绍和注意事项
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...
- springBoot--原理分析
起步依赖分析 分析spring-boot-starter-parent 按住Ctrl点击pom.xml中的spring-boot-starter-parent,跳转到了spring-boot-star ...
- SSRF打内网redis
0x00 redis基础 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统.Redis是一个开源的使用AN ...
- Solon 开发,一、注入或手动获取配置
Solon 开发 一.注入或手动获取配置 二.注入或手动获取Bean 三.构建一个Bean的三种方式 四.Bean 扫描的三种方式 五.切面与环绕拦截 六.提取Bean的函数进行定制开发 七.自定义注 ...
- 【经验总结】VSCode中找不到numpy/matplotlib/pillow,navigator没了
在VSCode中写python时,import numpy和matplotlib总是报错找不到模块,用conda list和pip list看到都安装了numpy,前后折腾了很久遇到了好几个问题: 无 ...
- 切换不同的echarts时,出现图标缩小,报警告,Can’t get dom width or height!
出现这样的原因是因为,在切换的时候,图表所对应的标签还没有显示出来,最好将代码放在$nextick里面执行,并且,采用使用v-if进行切换 转载:https://www.pianshen.com/ar ...
- python类和函数
#/usr/bin/python #coding=utf-8 class Car(): def __init__(self,name,year): self.name = name self.year ...