【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6035

【题目大意】

  给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值

【题解】

  我们计算单个颜色的贡献,那么就是经过该颜色至少一次的路径数量,
  我们统计的时候在每个点记录以其为开始的路径的答案和,
  统计的时候计算了点自身,同时有重复计算的部分,最后减去n除以2即可
  那么我们只要在每种颜色的虚树上统计即可。
  对于子树的贡献需要区间修改,我们在dfs序的差分数组上更改,最后求前缀和即可。  

【代码】

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <cstring>
  4. #include <vector>
  5. #include <list>
  6. using namespace std;
  7. const int M=200010,N=(M<<1)+10;
  8. int n,x,y,pre[N],st[N],en[N],c[N];
  9. vector<int> u[N],v[N];
  10. long long ans[N];
  11. list<int> l[N];
  12. int dfn;
  13. void dfs(int x,int fx){
  14. int cx=c[x];
  15. if(l[cx].empty())u[M+cx].push_back(x);
  16. else u[l[cx].back()].push_back(x);
  17. pre[x]=fx;
  18. l[cx].push_back(x);
  19. st[x]=dfn++;
  20. for(int i=0;i<v[x].size();i++){
  21. int y=v[x][i];
  22. if(y==fx)continue;
  23. dfs(y,x);
  24. }l[cx].pop_back();
  25. en[x]=dfn;
  26. }
  27. bool isson(int x,int y){return st[y]<=st[x]&&st[x]<en[y];}
  28. void Dfs(int x,int d){
  29. int pos=0;
  30. if(x<=M){
  31. ans[st[x]]+=n-d;
  32. ans[st[x]+1]-=n-d;
  33. }
  34. for(int i=0;i<v[x].size();i++){
  35. int y=v[x][i];
  36. if(y==pre[x])continue;
  37. int p=pos,size=en[y]-st[y];
  38. while(p<u[x].size()&&isson(u[x][p],y)){
  39. size-=en[u[x][p]]-st[u[x][p]];
  40. p++;
  41. }ans[st[y]]+=n-size-d;
  42. ans[en[y]]-=n-size-d;
  43. for(int j=pos;j<p;j++)Dfs(u[x][j],n-size);
  44. pos=p;
  45. }
  46. }
  47. int Cas=1;
  48. int main(){
  49. while(~scanf("%d",&n)){
  50. for(int i=1;i<=n;i++)scanf("%d",&c[i]);
  51. memset(ans,0,sizeof(ans));
  52. for(int i=0;i<N;i++)v[i].clear(),u[i].clear(),l[i].clear();
  53. dfn=1;
  54. for(int i=1;i<n;i++){
  55. scanf("%d%d",&x,&y);
  56. v[x].push_back(y);
  57. v[y].push_back(x);
  58. }dfs(1,1);
  59. for(int i=1;i<=M;i++){v[i+M].push_back(1);Dfs(i+M,0);}
  60. for(int i=1;i<=n;i++)ans[i]+=ans[i-1];
  61. long long Ans=0;
  62. for(int i=1;i<=n;i++)Ans+=ans[st[i]];
  63. printf("Case #%d: %lld\n",Cas++,(Ans-n)/2);
  64. }return 0;
  65. }

HDU 6035 Colorful Tree (树形DP)的更多相关文章

  1. HDU 6035 - Colorful Tree | 2017 Multi-University Training Contest 1

    /* HDU 6035 - Colorful Tree [ DFS,分块 ] 题意: n个节点的树,每个节点有一种颜色(1~n),一条路径的权值是这条路上不同的颜色的数量,问所有路径(n*(n-1)/ ...

  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 (2017 多校第一场 1003) 【树形dp】

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

  4. hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。

    /** 题目:hdu6035 Colorful Tree 链接: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(树形DP) 2017多校第一场

    题意:给出一棵树,树上的每个节点都有一个颜色,定义一种值为两点之间路径中不同颜色的个数,然后一棵树有n*(n-1)/2条 路径,求所有的路径的值加起来是多少. 思路:比赛的时候感觉是树形DP,但是脑袋 ...

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

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

  8. HDU 6035 Colorful Tree(dfs)

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

  9. hdu 6035 Colorful Tree(虚树)

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

随机推荐

  1. 关于auto-keras训练cnn模型

    # 我在训练自己的人脸分类模型的时候发现图片的维度不能太高,经过很多次测试过后觉得一般人脸图片分为28*28大小训练的效果比较好.建议在使用其训练自己的物体识别模型的时候,尽量把图片压缩到28*28# ...

  2. Android中的异常情况

    1.setText()方法中,如果参数是int类型,Android会把它当做是一个id查找,报以下异常,因此解决办法就是将参数转化为String类型 如:setText(num) è setText( ...

  3. CTSC/APIO2018 帝都一周游

    day0 报道 上午早早就起来了,两点才到酒店,然后去简单试了试机子. 不得不说今年八十中的伙食变得瓜皮了啊,去年还是大叠的5元卷,今年变成了单张的*餐卷.不知道食堂吝啬什么,面条米饭都只有一点点,还 ...

  4. 真正的上锁前,为何要调用preempt_disable()来关闭抢占的case【转】

    转自:http://blog.csdn.net/kasalyn/article/details/11473885 static inline void raw_spin_lock(raw_spinlo ...

  5. MySQL多线程复制故障(slave_pending_jobs_size_max)

    MySQL多线程复制故障(slave_pending_jobs_size_max) http://www.xuchanggang.cn/archives/1079.html

  6. 非 GUI 模式运行 JMeter 压力测试

    非 GUI 模式,即命令行模式,运行 JMeter 测试脚本能够大大缩减所需要的系统资源. 使用命令:jmeter -n -t <testplan filename> -l <lis ...

  7. [linux]通过ssh远程设定各服务器时间,从而实现集群时间同步

    #!/usr/bin/env bash #all hosts should to sync time, all hosts should no password login echo other sy ...

  8. Median_of_Two_Sorted_Arrays(理论支持和算法总结)

    可以将这个题目推广到更naive的情况,找两个排序数组中的第K个最大值(第K个最小值). 1.直接 merge 两个数组,然后求中位数(第K个最大值或者第K个最小值),能过,不过复杂度是 O(n + ...

  9. ASP.NET Core Module overview模块概述

    原文地址:ASP.NET Core Module overview By Tom Dykstra, Rick Strahl, and Chris Ross ASP.NET Core模块(ANCM)让你 ...

  10. mysql设置服务器编码

    今天写java程序的时候出现了插入mysql数据中文乱码问题,确定数据库和表的编码都已指定utf-8.百度后得知mysql安装后需设置服务器编码,以下是解决方法(ubuntu; mysql 5.6.2 ...