\(\mathcal{Description}\)

  Link & 双倍经验 Link.

  给定一棵 \(n\) 个结点的树,每个结点有一种颜色。记 \(g(u,v)\) 表示 \(u\) 到 \(v\) 简单路径上的颜色种数,求

\[\sum_{\{p_n\}}\sum_{i=1}^{n-1}g(p_i,p_{i+1})
\]

  其中 \(\{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」彩色树的更多相关文章

  1. Solution -「51nod 1514」美妙的序列

    \(\mathcal{Description}\)   Link.   称排列 \(\{p_n\}\) 美妙,当且仅当 \((\forall i\in[1,n))(\max_{j\in[1,i]}\{ ...

  2. Solution -「51nod 1355」斐波那契的最小公倍数

    \(\mathcal{Description}\)   Link.   令 \(f\) 为 \(\text{Fibonacci}\) 数列,给定 \(\{a_n\}\),求: \[\operatorn ...

  3. Solution -「51nod 1584」加权约数和

    \(\mathcal{Description}\)   Link.   令 \(\sigma(n)\) 为 \(n\) 的约数之和.求: \[\sum_{i=1}^n\sum_{j=1}^n\max\ ...

  4. 「WC 2019」数树

    「WC 2019」数树 一道涨姿势的EGF好题,官方题解我并没有完全看懂,尝试用指数型生成函数和组合意义的角度推了一波.考场上只得了 44 分也暴露了我在数数的一些基本套路上的不足,后面的 \(\ex ...

  5. [Luogu 3701] 「伪模板」主席树

    [Luogu 3701] 「伪模板」主席树 这是一道网络流,不是主席树,不是什么数据结构,而是网络流. 题目背景及描述都非常的暴力,以至于 Capella 在做此题的过程中不禁感到生命流逝. S 向 ...

  6. 【题解】#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT)

    [题解]#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT) 之前做这道题不理解,有一点走火入魔了,甚至想要一本近世代数来看,然后通过人类智慧思考后发现, ...

  7. Solution -「ARC 104E」Random LIS

    \(\mathcal{Description}\)   Link.   给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...

  8. Solution -「LOJ #6029」「雅礼集训 2017」市场

    \(\mathcal{Description}\)   Link.   维护序列 \(\lang a_n\rang\),支持 \(q\) 次如下操作: 区间加法: 区间下取整除法: 区间求最小值: 区 ...

  9. Solution -「NOI 2020」「洛谷 P6776」超现实树

    \(\mathcal{Description}\)   Link.   对于非空二叉树 \(T\),定义 \(\operatorname{grow}(T)\) 为所有能通过若干次"替换 \( ...

随机推荐

  1. antd-vue中给table表格整行加点击事件

    <a-table :columns="columns" :dataSource="data" :loading="loading" : ...

  2. Go语言读取各种配置文件

    配置文件结构体 config.go package config type System struct { Mode string `mapstructure:"mode" jso ...

  3. Word文档学习小练习链接

    1. < Word2010初学> https://www.toutiao.com/i6487370439910752782/ 2. <Word2010格式化可爱的家乡> htt ...

  4. Redis之持久化方式详解

    背景:Redis之所以能够在技术革新发展迅速的时代超越Memcache等其他Nosql数据库,最主要的一点是Redis提供数据持久化,能够根据持久化策略将缓存数据灵活的写到磁盘上,更好地满足了当下海量 ...

  5. 【记录一个问题】运算迁移到gpu后的计时问题

    我把部分计算迁移到GPU后,发现以帧率计算的程序,帧率下降:但是看各个函数的时间,又比之前减少了. 很奇怪,既然各个函数的时间减少,为什么帧率反而下降? 原来计算帧率使用了 gettimeofday( ...

  6. MySQL查询处理——逻辑查询处理和物理查询处理

    对于查询处理,可将其分为逻辑查询处理和物理查询处理.逻辑查询处理表示执行查询应该产生什么样的结果,而物理查询代表MySQL数据库是如何得到结果的. 逻辑查询处理 MySQL真正的执行顺序如下: (8) ...

  7. StringBuilder类练习

    1 package cn.itcast.p2.stringbuffer.demo; 2 3 public class StringBuilderTest { 4 public static void ...

  8. 推荐一个github国内访问加速神器GitHub520

    一.介绍 对 GitHub 说"爱"太难了:访问慢.图片加载不出来. 注: 本项目还处于测试阶段,仅在本机测试通过,如有问题欢迎提 issues 本项目无需安装任何程序,通过修改本 ...

  9. Kubernetes的Resource和Dashboard(十三)

    一.Resource和Dashboard 1.1.Resource 因为K8S的最小操作单元是Pod,所以这里主要讨论的是Pod的资源 官网:https://kubernetes.io/docs/co ...

  10. 6. java IO 流

    一.流的分类: * 1.操作数据单位:字节流.字符流 * 2.数据的流向:输入流.输出流 * 3.流的角色:节点流.处理流 *二.流的体系结构 * 抽象基类               节点流(或文件 ...