/*
HDU 6035 - Colorful Tree [ DFS,分块 ]
题意:
n个节点的树,每个节点有一种颜色(1~n),一条路径的权值是这条路上不同的颜色的数量,问所有路径(n*(n-1)/2条) 权值之和是多少?
分析:
考虑单种颜色,这种颜色的贡献是 至少经过一次这种颜色的路径数 = 总路径数(n*(n-1)/2) - 没有经过这种颜色的路径数
求没有经过这种颜色的路径数,即这种颜色的点将整棵树分块,每个分块中的总路径数
*/
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 200005;
struct Edge {
int to, next;
}edge[N<<1];
int tot, head[N];
void init() {
memset(head, -1, sizeof(head));
tot = 0;
}
void addedge(int u, int v) {
edge[tot].to = v; edge[tot].next = head[u];
head[u] = tot++;
}
int n;
int c[N], last[N], rem[N], cut[N];
LL ans;
LL sum2(LL x) {
return x*(x-1)/2;
}
int dfs(int u, int pre)
{
int su = 1, fa = last[c[u]];
last[c[u]] = u;
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if (v == pre) continue;
cut[u] = 0;
int sv = dfs(v, u);
su += sv;
ans -= sum2(sv-cut[u]);
}
(fa ? cut[fa] : rem[c[u]]) += su;
last[c[u]] = fa;
return su;
}
int main()
{
int tt = 0;
while (~scanf("%d", &n))
{
init();
for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
for (int i = 1; i < n; i++)
{
int x, y; scanf("%d%d", &x, &y);
addedge(x, y); addedge(y, x);
}
memset(last, 0, sizeof(last));
memset(cut, 0, sizeof(cut));
memset(rem, 0, sizeof(rem));
ans = n*sum2(n);
dfs(1, 1);
for (int i = 1; i <= n; i++)
ans -= sum2(n-rem[i]);
printf("Case #%d: %lld\n", ++tt, ans);
}
}
//----------------------------------------------------------------------
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 200005;
vector<int> c[N], G[N];
int n;
int L[N], R[N], s[N], f[N];
void dfs(int u, int pre, int&& ncnt)
{
f[u] = pre;
L[u] = ++ncnt;
s[u] = 1;
for (auto& v : G[u])
{
if (v == pre) continue;
dfs(v, u, move(ncnt));
s[u] += s[v];
}
R[u] = ncnt;
}
bool cmp(int a, int b) {
return L[a] < L[b];
}
int main()
{
int tt = 0;
while (~scanf("%d", &n))
{
for (int i = 0; i <= n; i++) c[i].clear(), G[i].clear();
for (int i = 1; i <= n; i++)
{
int x; scanf("%d", &x);
c[x].push_back(i);
}
for (int i = 1; i < n; i++)
{
int x, y; scanf("%d%d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
G[0].push_back(1);
dfs(0, 0, 0);
LL ans = (LL)n * n * (n-1)/2;
for (int i = 1; i <= n; i++)
{
if (c[i].empty()) {
ans -= (LL)n*(n-1)/2;
continue;
}
c[i].push_back(0);
sort(c[i].begin(), c[i].end(), cmp);
for (auto& x : c[i])
for (auto& y : G[x])
{
if (y == f[x]) continue;
int size = s[y];
int k = L[y];
while (1)
{
L[n+1] = k;
auto it = lower_bound(c[i].begin(), c[i].end(), n+1, cmp);
if (it == c[i].end() || L[*it] > R[y]) break;
size -= s[*it];
k = R[*it]+1;
}
ans -= (LL)size * (size-1)/2;
}
}
printf("Case #%d: %lld\n", ++tt, ans);
}
}

  

HDU 6035 - Colorful Tree | 2017 Multi-University Training Contest 1的更多相关文章

  1. hdu 6035:Colorful Tree (2017 多校第一场 1003) 【树形dp】

    题目链接 单独考虑每一种颜色,答案就是对于每种颜色至少经过一次这种的路径条数之和.反过来思考只需要求有多少条路径没有经过这种颜色即可. 具体实现过程比较复杂,很神奇的一个树形dp,下面给出一个含较详细 ...

  2. 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】

    Colorful Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  3. HDU 6035 Colorful Tree(补集思想+树形DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6035 [题目大意] 给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值 [题解] 单独考虑 ...

  4. HDU 6035 Colorful Tree (树形DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6035 [题目大意] 给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值 [题解] 我们计算 ...

  5. 2017ACM暑期多校联合训练 - Team 1 1003 HDU 6035 Colorful Tree (dfs)

    题目链接 Problem Description There is a tree with n nodes, each of which has a type of color represented ...

  6. HDU 6035 Colorful Tree(dfs)

    题意:一棵有n个点的树,树上每个点都有颜色c[i],定义每条路径的值为这条路径上经过的不同颜色数量和.求所有路径的值的和. 可以把问题转化为对每种颜色有多少条不同的路径至少经过这种颜色的点,然后加和. ...

  7. hdu 6035 Colorful Tree(虚树)

    考虑到树上操作:首先题目要我们求每条路径上出现不同颜色的数量,并把所有加起来得到答案:我们知道俩俩点之间会形成一条路径,所以我们可以知道每个样例的总的路径的数目为:n*(n-1)/2: 这样单单的求, ...

  8. HDU 6170 - Two strings | 2017 ZJUT Multi-University Training 9

    /* HDU 6170 - Two strings [ DP ] | 2017 ZJUT Multi-University Training 9 题意: 定义*可以匹配任意长度,.可以匹配任意字符,问 ...

  9. hdu 6301 Distinct Values (2018 Multi-University Training Contest 1 1004)

    Distinct Values Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

随机推荐

  1. 【Python】【demo实验17】【练习实例】【将一个正整数分解质因数】

    题目:将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. 我的源代码: #!/usr/bin/python # encoding=utf-8 # -*- coding: UTF-8 ...

  2. 协议相关(HTTP,TCP,webservice,socket)

    什么是协议? 我们常常点开的链接(URL)就有HTTP.HTTPS协议 枯燥点的知识(协议模型) HTTP,webservice都是在<TCP/IP协议>的应用层. TCP,socket在 ...

  3. Codeforces 1237F. Balanced Domino Placements

    传送门 很妙的题 首先先考虑一个简化的问题,现在有一行格子让你填 你要么填一格 要么填两格 有的格子不让你填 问你填了 $a$ 个一格和填了 $b$ 个两格有多少种方案 那么显然先只考虑放两格的方案, ...

  4. 啥叫K8s?啥是k8s?

    •Kubernetes介绍 1.背景介绍 云计算飞速发展 - IaaS - PaaS - SaaS Docker技术突飞猛进 - 一次构建,到处运行 - 容器的快速轻量 - 完整的生态环境 2.什么是 ...

  5. 如何配置数据库镜像<一>

    一.简介 “数据库镜像”是Sql Server 2005推出的一个主要用于提高数据库可用率的软件解决方案.镜像是基于每个数据库执行的,仅适用于使用完整恢复模式的数据库.简单恢复模式和大容量日志恢复模式 ...

  6. CSS 小工具集

    http://www.colorzilla.com/gradient-editor/css渐变生成工具.http://linxz.github.io/tianyizone/css志爷小工具.http: ...

  7. PMP - 风险识别之风险登记册

    目录 PMP - 风险识别之风险登记册 1. 风险登记册 1.1 已识别风险的清单 1.2 潜在风险责任人 1.3 潜在风险应对措施清单 2. 相关习题 2.1 风险发生的时候,要实施 风险登记册 上 ...

  8. cpu 100%怎样定位

    先用top定位最耗cpu的java进程 例如: 12430工具:top或者 htop(高级)方法:top -c 显示进程运行详细列表键入 P (大写P),按照cpu进行排序 然后用top -p 124 ...

  9. 一种移动端position:absolute布局:

    一种移动端position:absolute布局:   1.他父级不需要加上 position:relative; 如果父级不是不是body,则加position:absolute; 2.红色加量部分 ...

  10. shell脚本视频学习1

     一.知识点:变量,参数传递 练习1:使用shell脚本,输出当前所在的目录 练习2:计算/etc目录下有多少个文件,用shell脚本实现 ls -l--->数一下, ls -l|wc -l ( ...