\(\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}\)

  1. /* Clearink */
  2. #include <cstdio>
  3. #include <vector>
  4. #include <algorithm>
  5. #define rep( i, l, r ) for ( int i = l, repEnd##i = r; i <= repEnd##i; ++i )
  6. #define per( i, r, l ) for ( int i = r, repEnd##i = l; i >= repEnd##i; --i )
  7. inline int rint () {
  8. int x = 0, f = 1; char s = getchar ();
  9. for ( ; s < '0' || '9' < s; s = getchar () ) f = s == '-' ? -f : f;
  10. for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
  11. return x * f;
  12. }
  13. const int MAXN = 1e5, MOD = 1e9 + 7;
  14. int n, ecnt, ans, clr[MAXN + 5], head[MAXN + 5], siz[MAXN + 5], sum[MAXN + 5];
  15. struct Edge { int to, nxt; } graph[MAXN * 2 + 5];
  16. inline int mul ( const long long a, const int b ) { return a * b % MOD; }
  17. inline int sub ( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
  18. inline int add ( int a, const int b ) { return ( a += b ) < MOD ? a : a - MOD; }
  19. inline void link ( const int s, const int t ) {
  20. graph[++ecnt] = { t, head[s] };
  21. head[s] = ecnt;
  22. }
  23. inline int count ( const int s ) { return ( s * ( s - 1ll ) >> 1 ) % MOD; }
  24. inline void dfs ( const int u, const int fa ) {
  25. siz[u] = 1, ++sum[clr[u]];
  26. for ( int i = head[u], v; i; i = graph[i].nxt ) {
  27. if ( ( v = graph[i].to ) ^ fa ) {
  28. int s = sum[clr[u]];
  29. dfs ( v, u ), siz[u] += siz[v];
  30. int t = sum[clr[u]], dlt = t - s;
  31. ans = add ( ans, count ( siz[v] - dlt ) );
  32. sum[clr[u]] += siz[v] - dlt;
  33. }
  34. }
  35. }
  36. int main () {
  37. n = rint ();
  38. rep ( i, 1, n ) clr[i] = rint ();
  39. for ( int i = 1, u, v; i < n; ++i ) {
  40. u = rint (), v = rint ();
  41. link ( u, v ), link ( v, u );
  42. }
  43. dfs ( 1, 0 );
  44. rep ( c, 1, n ) {
  45. if ( c ^ clr[1] ) {
  46. ans = add ( ans, count ( n - sum[c] ) );
  47. }
  48. }
  49. ans = sub ( mul ( n, count ( n ) ), ans );
  50. int fct = 1;
  51. rep ( i, 1, n - 2 ) fct = mul ( fct, i );
  52. printf ( "%d", mul ( ans, mul ( 2, mul ( n - 1, fct ) ) ) );
  53. return 0;
  54. }

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. NIO【同步非阻塞io模型】关于 文件io 的总结

    1.前言 这一篇随笔是写 NIO 关于文件输入输出的总结 /* 总结: 1.io操作包括 socket io ,file io ; 2.在nio模型,file io使用fileChannel 管道 , ...

  2. Python调用aiohttp

    1. aiohttp安装 pip install aiohttp 1.1. 基本请求用法 async with aiohttp.get('https://github.com') as r: awai ...

  3. 只需两步在Linux系统安装百度网盘--Ubuntu20

    Linux Ubuntu系统安装百度网盘 百度网盘已支持Linux系统下载和使用.使用Linux系统下载并安装一个百度网盘是非常简单的,只需要以下两个步骤: 第一步 进入官网下载.deb类型的百度网盘 ...

  4. kafka入门(采坑)笔记

    前言 之前在工作和学习过程中也会有记笔记的习惯,但是没有发布出来,也因最近各方面的瓶颈急需突破和提升,所以还是要很积极的融入大环境大生态中,好废话不多说,说下这次遇到的问题 第一步启动zk 根据教程安 ...

  5. 同步gitlab与github

    1.找到setting 2.找到左下方的developer setting 3.按标好的数字依次执行 4.填写note并勾选repo 5.在最左下方勾选 6.保存生成的新的token到其他地方,之后你 ...

  6. IPV4地址,子网掩码,子网划分

    转载自https://blog.csdn.net/qq_45108415/article/details/114179407

  7. VS2017:win32项目与win32控制台应用程序的转换方法

    原文:https://www.cnblogs.com/asuser/articles/12297251.html 刚开始使用VS2017新建项目工程时,有时把应用类型的工程建成控制台类型的工程,在编译 ...

  8. 哪些是GET请求,哪些是POST请求

    GET请求: 1,form标签 method=get 2,a标签 3,link标签引入css 4,Script标签引入js文件 5,img标签引入图片 6,iframe引入html页面 7,在浏览器地 ...

  9. 集合框架-Vector集合

    1 package cn.itcast.p1.vector.demo; 2 3 import java.util.Enumeration; 4 import java.util.Iterator; 5 ...

  10. python3 类的学习

    # -*-coding:utf-8-*- # 定义类是通过class关键字,class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来 ...