/*
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. mysql函数使用报错

    This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de 错误解决办法 解决办法也有两种,第一种是在创建 ...

  2. 数据库连接池的sqlhelper

    import pymysql import threading from DBUtils.PooledDB import PooledDB """ storage = { ...

  3. T100——自动执行设置了但没执行

    azzi950设置了背景定时执行,但到底没执行, 重启的命令如下.三个命令都执行一下.指令 1: r.r azzp950 kill 指令 2: r.r azzp951 kill 指令 3: r.r a ...

  4. Jmeter之JDBC取样器(数据库增删改查)

    1.将数据库的jar包存入jmeter/lib目录下 2.配置jmeter 测试计划中“添加jar包” 数据库访问配置:线程组->添加->配置原件->JDBC Connection ...

  5. X86逆向6:易语言程序的DIY

    易语言程序在中国的用户量还是很大的,广泛用于外挂的开发,和一些小工具的编写,今天我们就来看下如何给易语言程序DIY,这里是用的易语言演示,当然这门技术也是可以应用到任何一门编译型语言中的,只要掌握合适 ...

  6. zabbix-自定义告警(二)

    实现自定义监控 文章引用:https://www.cnblogs.com/clsn/p/7885990.html#auto_id_28 一.实现自定义监控 说明zabbix自带模板Template O ...

  7. Javascript——数据类型 和 注释

    数据类型:JavaScript中包括如下7种数据类型:字符串.数字.布尔.数组.对象.null.undefined 字符串: 注意:字符串类型的数据需要使用单引号或双引号引起来. 数字: 注意:Jav ...

  8. Unity Button按钮延迟

    1.把下面脚本放到Editor文件夹下,这样脚本继承Button之后,新声明的public变量才能在Inspector面板显示出来. using System.Collections; using S ...

  9. C# 日期格式化以及日期常用方法

    一.日期格式化 1.ToString() d 月中的某一天.一位数的日期没有前导零. dd 月中的某一天.一位数的日期有一个前导零. ddd 周中某天的缩写名称,在 AbbreviatedDayNam ...

  10. 【weixin】微信支付---Native支付模式一

    [模式一]:商户后台系统根据微信支付规则链接生成二维码,链接中带固定参数productid(可定义为产品标识或订单号).用户扫码后,微信支付系统将productid和用户唯一标识(openid)回调商 ...