2478. [HZOI 2016]简单的最近公共祖先

★☆   输入文件:easy_LCA.in   输出文件:easy_LCA.out   简单对比
时间限制:2 s   内存限制:128 MB

【题目描述】

给定一棵有n个节点的有根树,根节点为1,每个节点有一个权值wi,求

即求所有无序节点对的LCA的权值之和。

树的节点编号为1~n,LCA表示两节点的最近公共祖先,即在它们的所有公共祖先中离根节点最远的节点。

【输入格式】

第一行一个整数n,表示节点数。

第二行n个正整数,表示每个点的权值。

以下n-1行每行两个整数x,y,表示树上有一条边连接节点x和节点y。

【输出格式】

一个整数,表示答案。

【样例输入】

  1. 3
  2. 1 2 3
  3. 1 2
  4. 1 3

【样例输出】

  1. 9

【数据范围与约定】

对于30%的数据,n<=1000。

对于60%的数据,n<=100000。

对于100%的数据,1<=n<=1000000,0<wi<=1000000。

【来源】

HZOI 2016

思路:

看到这个题我上来就写lca然后·成功的T成了狗、、、、

呜呜呜~~~~(>_<)~~~~

某位大佬说这个题要用dfs+乱搞,然后就可以A掉、、、

至于怎么来做,我们看下面的分析

我们来看一下左图。

首先,我们枚举每一个lca,然后判断他里面有几个节点(某大佬:其实不用枚举的,我们直接dfs就好了,这样什么都出来了、、、)

好,我们按照这位大佬的思路来、、、

我们先从1号节点来枚举,看下图

在这里我们先从一号节点开始,找与他相连的子树,在这里为了方便,我们先给它标上号,一号节点一共有5颗子树,首先,我们知道,1号节点与1号子树内的所有节点的最近公共祖先是1号节点本身对吧?!既然这样,我们可以组出来1*3个组合对吧?!也就是说现在我们一共有1*3个节点以1号节点为lca

然后我们再看下图。

然后我们知道1号节点和1号子树内的点跟2号子树内的点的lca一定是1号节点对吧,既然如此我们就把1号节点与1号子树内的节点个数合并起来,也就是4,这4个节点与2号节点内的4个点的lca仍为1

以此类推,我们把合并起来的1号子树在与2号子树合并,然后他们与3号子树的lca仍然是1号节点、、、、、

这样,我们就可以得到所有的lca权值之和。

但是我们发现,我们这个题里有lca(i,i)这样的点对吧,我们肯定知道这样的点的lca就是他本身,然后我们最后求解出ans后枚举每一个点再将他们的权值加上就好了!

代码:

  1. #include<cstdio>
  2. #include<vector>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<iostream>
  6. #include<algorithm>
  7. #define N 1000010
  8. using namespace std;
  9. vector<int>vec[N];
  10. int n,x,y;
  11. ];
  12. int read()
  13. {
  14. ,f=; char ch=getchar();
  15. ; ch=getchar();}
  16. +ch-'; ch=getchar();}
  17. return x*f;
  18. }
  19. int dfs(int x)
  20. {
  21. deep[x]=deep[fa[x][]]+;
  22. ;fa[x][i];i++)
  23. fa[x][i+]=fa[fa[x][i]][i];
  24. ;i<vec[x].size();i++)
  25. if(!deep[vec[x][i]])
  26. fa[vec[x][i]][]=x,dfs(vec[x][i]);
  27. }
  28. int lca(int x,int y)
  29. {
  30. if(deep[x]>deep[y]) swap(x,y);
  31. ;i>=;i--)
  32. if(deep[fa[y][i]]>=deep[x])
  33. y=fa[y][i];
  34. if(x==y) return x;
  35. ;i>=;i--)
  36. if(fa[x][i]!=fa[y][i])
  37. x=fa[x][i],y=fa[y][i];
  38. ];
  39. }
  40. int main()
  41. {
  42. freopen("easy_LCA.in","r",stdin);
  43. freopen("easy_LCA.out","w",stdout);
  44. n=read();;
  45. ;i<=n;i++) a[i]=read();
  46. ;i<n;i++)
  47. {
  48. x=read(),y=read();
  49. vec[x].push_back(y);
  50. vec[y].push_back(x);
  51. }
  52. deep[]=;
  53. dfs();
  54. ;i<=n;i++)
  55. ;j<=i;j++)
  56. if(i==j) ans+=a[i];
  57. else ans+=a[lca(i,j)];
  58. printf("%lld",ans);
  59. ;
  60. }

lca T成狗、、、、

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #define N 1000100
  7. using namespace std;
  8. int n,x,y,tot;
  9. long long w[N],fa[N],sum[N],ans,head[N];
  10. int read()
  11. {
  12. ,f=;char ch=getchar();
  13. ; ch=getchar();}
  14. +ch-'; ch=getchar();}
  15. return x*f;
  16. }
  17. struct Edge
  18. {
  19. int to,next;
  20. }edge[N<<];
  21. int add(int x,int y)
  22. {
  23. tot++;
  24. edge[tot].to=y;
  25. edge[tot].next=head[x];
  26. head[x]=tot;
  27. }
  28. int dfs(int x)
  29. {
  30. sum[x]=;
  31. for(int i=head[x];i;i=edge[i].next)
  32. {
  33. int to=edge[i].to;
  34. if(to!=fa[x])
  35. {
  36. fa[to]=x;dfs(to);
  37. ans+=(long long)sum[x]*sum[to]*(long long)w[x];
  38. sum[x]+=(long long)sum[to];
  39. }
  40. }
  41. }
  42. int main()
  43. {
  44. freopen("easy_LCA.in","r",stdin);
  45. freopen("easy_LCA.out","w",stdout);
  46. n=read();
  47. ;i<=n;i++) w[i]=read();
  48. ;i<n;i++)
  49. {
  50. x=read(),y=read();
  51. add(x,y);add(y,x);
  52. }
  53. dfs();
  54. ;i<=n;i++) ans+=(long long)w[i];
  55. printf("%lld",ans);
  56. ;
  57. }

cogs——2478. [HZOI 2016]简单的最近公共祖先的更多相关文章

  1. cogs 2478. [HZOI 2016]简单的最近公共祖先

    2478. [HZOI 2016]简单的最近公共祖先 ★☆   输入文件:easy_LCA.in   输出文件:easy_LCA.out   简单对比时间限制:2 s   内存限制:128 MB [题 ...

  2. COGS——T 2478. [HZOI 2016]简单的最近公共祖先

    http://www.cogs.pro/cogs/problem/problem.php?pid=2478 ★☆   输入文件:easy_LCA.in   输出文件:easy_LCA.out   简单 ...

  3. COGS 2421.[HZOI 2016]简单的Treap 题解

    题目大意: 给定n个数及其优先级,求对应的符合最小堆性质的Treap的先序遍历. n<=500000. 解法: 目前为止我只想到了三种解法,其中第三种是正解. 1.暴力1 以优先级为关键字排序, ...

  4. [COGS 2421] [HZOI 2016] 简单的Treap 笛卡尔树

    笛卡尔树就是你给两维限制,一维堆R,一维二叉搜索树K,平地拔起一棵Treap,最广范的应用:用LCA求区间最值,建Treap,还有个什么范围top k我表示并不会查都查不到.它最妙最高的地方在于用栈来 ...

  5. [补档][HZOI 2016]简单的Treap

    [HZOI 2016]简单的Treap 题目 Treap是一种平衡二叉搜索树,除二叉搜索树的基本性质外,Treap还满足一个性质: 每个节点都有一个确定的优先级,且每个节点的优先级都比它的两个儿子小( ...

  6. COGS 2199. [HZOI 2016] 活动投票

    2199. [HZOI 2016] 活动投票 ★★   输入文件:hztp.in   输出文件:hztp.out   简单对比时间限制:0.5 s   内存限制:2 MB [题目描述] 衡中活动很多, ...

  7. COGS 2485. [HZOI 2016]从零开始的序列

    2485. [HZOI 2016]从零开始的序列 ★★   输入文件:sky_seq.in   输出文件:sky_seq.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] ...

  8. cogs——2419. [HZOI 2016]公路修建2

    2419. [HZOI 2016]公路修建2 ★☆   输入文件:hzoi_road2.in   输出文件:hzoi_road2.out   简单对比时间限制:1 s   内存限制:128 MB [题 ...

  9. cogs——2416. [HZOI 2016]公路修建

    2416. [HZOI 2016]公路修建 ★☆   输入文件:hzoi_road.in   输出文件:hzoi_road.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述 ...

随机推荐

  1. 几种不同程序语言的HMM版本

    几种不同程序语言的HMM版本 “纸上得来终觉浅,绝知此事要躬行”,在继续翻译<HMM学习最佳范例>之前,这里先补充几个不同程序语言实现的HMM版本,主要参考了维基百科.读者有兴趣的话可以研 ...

  2. Java实现链式存储的二叉树

    二叉树的定义: 二叉树(BinaryTree)是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的.分别称作这个根的左子树和右子树的二叉树组成. 二叉树的遍历方式主要 ...

  3. GridControl详解(五)设置行备注和行号

    备注显示设置 设置备注字段 显示结果: 可以写入按键事件F3,用以开关备注显示 private void Form4_KeyUp(object sender, KeyEventArgs e) { if ...

  4. angular 开发之proxy

    创建proxy配置文件proxy.conf.json 内容如下  {   "/api/*": { "target": "https://abc.com ...

  5. 树形DP初探•总结

    这几天,我自学了基础的树形DP,在此给大家分享一下我的心得.   首先,树形DP这种题主要就是解决有明确分层次且无环的树上动态规划的题.这种题型一般(注意只是基础.普通的情况下)用深度优先搜索来解决实 ...

  6. 【洛谷 P4166】 [SCOI2007]最大土地面积(凸包,旋转卡壳)

    题目链接 又调了我两个多小时巨亏 直接\(O(n^4)\)枚举4个点显然不行. 数据范围提示我们需要一个\(O(n^2)\)的算法. 于是\(O(n^2)\)枚举对角线,然后在这两个点两边各找一个点使 ...

  7. 生成验证码tp

    js里拼接随机数 页面上链接 去掉后缀名

  8. android内存回收顺序

    最近做项目的时候,经常会考虑到系统回收进程,释放资源等问题.特别查找了相关资料,了解下android内存回收顺序以及回收场景. 下面内容都为网络查找资料,若有错误,欢迎指出. 以下顺序,依次被回收的可 ...

  9. angular 最大字数限制

    js可以通过onkeyup onkeydown判断当前节点字数. angular可以通过监听的方式: $scope.input = {//初始化,避免ng-model绑定取不到值 MaxBT:'', ...

  10. elk系列1之入门安装与基本操作【转】

    preface 我们每天都要查看服务器的日志,一方面是为了开发的同事翻找日志,另一方面是巡检服务器查看日志,而随着服务器数量以及越来越多的业务上线,日志越来越多,人肉运维相当痛苦了,此时,参考现在非常 ...