题目来源: HackerRank
基准时间限制:3 秒 空间限制:131072 KB 分值: 640

一个初始为空的二叉搜索树T,以及1到N的一个排列P: {a1, a2, ..., aN}。我们向这个二叉搜索树T添加这些数,从a1开始, 接下来是 a2, ..., 以aN结束。在每一个添加操作后,输出T上每对节点之间的距离之和。
例如:4 7 3 1 8 2 6 5。最终的二叉树为:
 
       4
     /   \
    3      7   
  /      /   \
 1      6     8
  \    /
   2  5

 
节点两两之间的距离和 = 6+5+5+4+3+2+1+5+4+4+3+2+1+4+3+3+2+1+3+2+2+1+2+1+1+2+1+3 = 76

Input
第1行:1个数N。(1 <= N <= 100000)
第2 - N + 1行:每行1个数,对应排列的元素。(1 <= ai <= N)
Output
输出共N行,每行1个数,对应添加当前元素后,每对节点之间的距离之和。
Input示例
8
4
7
3
1
8
2
6
5
Output示例
0
1
4
10
20
35
52
76

树 规律题 动态点分治

直接模拟建树妥妥被卡。

分析一波可以发现,将一个点x添加进树的时候,在所有已有点中找到x的前驱和后继,x要么是前驱的右儿子,要么是前驱的左儿子。

思考一下或者手玩一波会发现“前驱的右儿子”和“后继的左儿子“不会同时为空,所以要添加到哪里是确定的。

我们可以离线操作,先将树建好,之后按顺序每次添加一个点,统计它到所有已有点的距离。

剩下的部分显然是动态点分治模板题。

写完WA了一半点,旁边czy说:“想必没有开LL”

开了LL以后还有三个点WA,旁边czy说:“想必数组不够大”

开大了数组就AC辣

他真是个小天才!

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<cmath>
  6 #include<set>
  7 #define LL long long
  8 using namespace std;
  9 const int INF=0x3f3f3f3f;
 10 const int mxn=150010;
 11 int read(){
 12     int x=0,f=1;char ch=getchar();
 13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
 15     return x*f;
 16 }
 17 struct edge{
 18     int v,nxt;
 19 }e[mxn<<1];
 20 int hd[mxn],mct=0;
 21 void add_edge(int u,int v){
 22     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
 23 }
 24 void insert(int u,int v){
 25     add_edge(u,v);add_edge(v,u);return;
 26 }
 27 int sz[mxn],mc[mxn],rot,smm;
 28 int dep[mxn],dis[mxn][23];
 29 int an[mxn][23];
 30 LL ans1[mxn],ans2[mxn],num[mxn];
 31 LL nowans;
 32 bool vis[mxn];
 33 void DFS_sz(int u,int fa){
 34     sz[u]=mc[u]=1;
 35     for(int i=hd[u];i;i=e[i].nxt){
 36         int v=e[i].v;;if(v==fa || vis[v])continue;
 37         DFS_sz(v,u);
 38         sz[u]+=sz[v];
 39         mc[u]=(sz[v]>mc[u])?sz[v]:mc[u];
 40     }
 41     mc[u]=max(mc[u],smm-sz[u]);
 42     if(mc[u]<mc[rot])rot=u;
 43     return;
 44 }
 45 void calc(int u,int fa,int ance,int dist){
 46     an[u][++dep[u]]=ance;
 47     dis[u][dep[u]]=dist;
 48     for(int i=hd[u];i;i=e[i].nxt){
 49         int v=e[i].v;
 50         if(v==fa || vis[v])continue;
 51         calc(v,u,ance,dist+1);
 52     }
 53     return;
 54 }
 55 void solve(int x){
 56     vis[x]=1;
 57 //    printf("solve:%d\n",x);
 58     calc(x,x,x,0);dep[x]--;
 59     for(int i=hd[x];i;i=e[i].nxt){
 60         int v=e[i].v;
 61         if(!vis[v]){
 62             smm=sz[v]; mc[rot=0]=INF;
 63             DFS_sz(v,x);
 64             solve(rot);
 65         }
 66     }
 67     return;
 68 }
 69 void add(int u){
 70     LL tmp=ans1[u];
 71     for(int i=dep[u];i>1;i--){
 72         LL dist=dis[u][i-1];
 73         tmp+=ans1[an[u][i-1]]-ans2[an[u][i]];
 74         tmp+=dist*(num[an[u][i-1]]-num[an[u][i]]);
 75     }
 76     nowans+=tmp;
 77     num[u]+=1;
 78     for(int i=dep[u];i>1;i--){
 79         LL dist=dis[u][i-1];
 80         ans1[an[u][i-1]]+=dist*1;
 81         ans2[an[u][i]]+=dist*1;
 82         num[an[u][i-1]]+=1;
 83     }
 84     return;
 85 }
 86 //
 87 int ch[mxn][2];
 88 //int st[mxn],top=0;
 89 int n,x[mxn],M[mxn],U[mxn];
 90 set<int>st;
 91 void init(){
 92     st.insert(x[1]);set<int>::iterator it,it2;
 93     for(int i=2;i<=n;i++){
 94         st.insert(x[i]);
 95         it=it2=st.lower_bound(x[i]);
 96         if(it!=st.end()){it++;if(it!=st.end())U[i]=(*it);}
 97         if(it2!=st.begin()){it2--; M[i]=(*it2);}
 98     }
 99     for(int i=2;i<=n;i++){
100         if(!M[i] || ch[M[i]][1]){
101             ch[U[i]][0]=x[i];
102             insert(U[i],x[i]);
103             continue;
104         }
105         if(!U[i] || ch[U[i]][0]){
106             ch[M[i]][1]=x[i];
107             insert(M[i],x[i]);
108         }
109     }
110     return;
111 }
112 int main(){
113     int i,j;
114     n=read();
115     for(i=1;i<=n;i++)x[i]=read();
116     init();
117     smm=n;
118     mc[rot=0]=INF;
119     DFS_sz(1,0);
120     solve(rot);
121     for(i=1;i<=n;i++){
122         an[i][++dep[i]]=i;
123         dis[i][dep[i]]=0;
124     }
125     for(i=1;i<=n;i++){
126         add(x[i]);
127         printf("%lld\n",nowans);
128     }
129     return 0;
130 }

转载于:https://www.cnblogs.com/SilverNebula/p/7095498.html

51nod1297 管理二叉树相关推荐

  1. 数据结构-----二叉树,树,森林之间的转换

    图片和转换步骤来自这里 本文主要描述具体实现 用一种略微老土的话描述: 二叉树:每一节点最多有2个子节点,左边的叫左节点,右边的叫右节点,自己叫根节点. 树:每个节点的子节点数量不受限制. 森林:由若 ...

  2. 树的基本概念和遍历规则 数据结构和算法 二叉树遍历(前序、中序、后序、层次、深度优先、广度优先遍历)

    zsychanpin 博客园 首页 新随笔 联系 订阅 管理 树的基本概念和遍历规则 树的递归定义 树是n(n>0)个结点的有限集,这个集合满足下面条件:       ⑴有且仅有一个结点没有前驱 ...

  3. python中怎么统计英文字符的个数_【Python练习1】统计一串字符中英文字母、空格、数字和其他字符的个数...

    练习思路: 1.输入一串字符 2.筛选出字符中的英文字母并统计 3.筛选出字符中的空格并统计 4.筛选出字符中的数字并统计 5.筛选出字符中的其他字符并统计 代码实现: def msg(s): abc ...

  4. bartender一行打印两个二次开发_C++ 智能指针和二叉树:图解层序遍历和逐层打印二叉树...

    作者:apocelipes  链接:https://www.cnblogs.com/apocelipes/p/10758692.html 二叉树是极为常见的数据结构,关于如何遍历其中元素的文章更是数不 ...

  5. .net内存管理与指针

    本人前段时间准备做个TIN三角网的程序,思想是是分割合并法,分割的同时建立平衡二叉树,然后子树建三角网并相互合并,再向上加入父亲的点集.由于我对.net语言熟点,就准备用c#语言实现.但是不知从那听过 ...

  6. 关于二叉树的几个必须掌握的实现

    The best way to end your fear is to face it yourself.  结束恐惧的最佳办法就是自己面对. 本分分享了二叉搜索树的几种实现,由简入繁.说句题外话,马 ...

  7. BSP场景管理方法简介

    BSP(Binary Space Partition,二叉空间分割)方法,在大型3d游戏场景管理方面,可以认为是已经证明了的,最成熟的,最经得起考验的场景管理方法.诸如虚幻系列引擎(Unreal 1, ...

  8. 二叉链表和职工管理系统结合_基于二叉链表的二叉树实现

    main.c// 数据结构实验三 Created by 南隹 on 2019/11/12.// Copyright © 2019 南隹. All rights reserved.//以下代码部分功能需 ...

  9. sdh管理单元指针_C语言学习|指针的介绍

    指针是C语言提供的一种特殊而又有非常重要的数据类型. 联合使用指针和结构体这两种数据类型可以有效地表示许多复杂的数据结构,如队列.堆栈.链表.树.图等. 指针这个内容为什么那么的重要? 1.指针为函数 ...

最新文章

  1. 使用alterMIME实现添加message footer功能
  2. CENTOS在输入ifconfig命令时,提示没有命令的处理方法
  3. springboot整个缓存_SpringBoot中整合Redis(缓存篇)
  4. 多线程与高并发(五):强软弱虚四种引用以及ThreadLocal的原理与源码
  5. python二分法查找程序_Python程序查找最大EVEN数
  6. java8新特性以及原因_JAVA8 十大新特性详解
  7. Batch批量替换hosts
  8. 资产模型数据初始化时应注意的事项
  9. 开关电源雷击浪涌整改_高频开关电源的EMC电磁兼容整改问题分析
  10. 汇编的接触——基础知识
  11. Hibernate相关内容
  12. 记账系统推荐金蝶精斗云_金蝶精斗云的免费财务做账软件有哪些?
  13. c#中使用BackgroundWorker
  14. 启动计算机管理服务,win10系统打开服务管理器的五种方法
  15. Python手游辅助教程之战双帕弥什脚本教程
  16. 计算机病毒模块测试题,计算机病毒分类测试题集
  17. Google SketchUp SDK
  18. L1-009 N个数求和---题解
  19. PHP Imagick发光文字
  20. 黑盒测试方法-----状态转换图

热门文章

  1. VSFLEXgrid控件几个特殊的属性方法的使用
  2. AndroidStudio_安卓原生开发_android10中android11中_bitmap缩放大小不一致_解决方案---Android原生开发工作笔记154
  3. JAVA高并发工作笔记0001---高并发编程之ConcurrentLinkedDeque
  4. 数据库工作笔记008---pg_hba.conf entry for host “192.168.2.111”, user “gpadmin”, database “template1”, SSL
  5. SpringCloud工作笔记031---Idea中JDK为1.8,还提示Diamond types are not supported at this language level
  6. sphereface conv64
  7. kafka集群安装部署
  8. pclint 与vs2010结合识别预处理器定义
  9. shell读取mysql_shell读取mysql数据库
  10. 随想录(软件中的bug)