一个初始为空的二叉搜索树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个数,对应添加当前元素后,每对节点之间的距离之和。

  先把树求出来。。具体的话就是每次添加元素之后,找到这个数的前驱后继,哪个有空位这个元素就在哪。随便写个什么数据结构。

  求节点的距离和的话。。我写了点分治,每次查找完往里面加点...查找啊去重啊什么的都是一样的套路...

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstdlib>
#include<bitset>
//#include<ctime>
#define ll long long
#define ull unsigned long long
#define ui unsigned int
#define d double
//#define ld long double
using namespace std;
const int maxn=,mxnode=maxn;
struct zs{int too,pre;}e[maxn<<];int tot,last[maxn];
int lc[mxnode],rc[mxnode],v[mxnode],rnd[mxnode],tt;int V,PRE,AFT,rt;bool u[maxn][];
int sz[maxn],mx[maxn],RT,POI,dis[maxn],st[maxn],top,mxdep[maxn];bool del[maxn];
int bel[maxn][],belson[maxn<<][],dist[maxn][],_sz[maxn],_sonsz[maxn<<];int ID;
ll _sum[maxn],_sonsum[maxn<<];
int a[maxn];
int i,j,k,n,m; int ra,fh;char rx;
inline int read(){
rx=getchar(),ra=,fh=;
while((rx<''||rx>'')&&rx!='-')rx=getchar();
if(rx=='-')fh=-,rx=getchar();
while(rx>=''&&rx<='')ra=ra*+rx-,rx=getchar();return ra*fh;
}
inline void maxs(int &a,int b){if(b>a)a=b;}
inline void lturn(int &x){int R=rc[x];rc[x]=lc[R],lc[R]=x,x=R;}
inline void rturn(int &x){int L=lc[x];lc[x]=rc[L],rc[L]=x,x=L;}
inline void insert(int &x){
if(!x){x=++tt,v[x]=V,rnd[x]=rand();return;}
if(V<v[x]){
insert(lc[x]);
if(rnd[lc[x]]<rnd[x])rturn(x);
}else{
insert(rc[x]);
if(rnd[rc[x]]<rnd[x])lturn(x);
}
}
void getpre(int x){
if(!x)return;
if(v[x]<V)PRE=v[x],getpre(rc[x]);else getpre(lc[x]);
}
void getaft(int x){
if(!x)return;
if(v[x]>V)AFT=v[x],getaft(lc[x]);else getaft(rc[x]);
}
inline void ins(int a,int b){
e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;
e[++tot].too=a,e[tot].pre=last[b],last[b]=tot;
} void getrt(int x,int fa){
sz[x]=,mx[x]=;
for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa&&!del[e[i].too])
getrt(e[i].too,x),maxs(mx[x],sz[e[i].too]),sz[x]+=sz[e[i].too];
maxs(mx[x],POI-sz[x]);
if(mx[x]<mx[RT])RT=x;
}
void getpoi(int x,int fa){
dis[x]=dis[fa]+,st[++top]=x,sz[x]=;
for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa&&!del[e[i].too])
getpoi(e[i].too,x),sz[x]+=sz[e[i].too];
}
void work(int x,int dep){
int i,p;
RT=,getrt(x,),x=RT,mxdep[x]=dep,bel[x][dep]=x,dist[x][dep]=dis[x]=;
for(i=last[x];i;i=e[i].pre)if(!del[e[i].too]){
getpoi(e[i].too,x);ID++;
while(top)p=st[top--],bel[p][dep]=x,belson[p][dep]=ID,dist[p][dep]=dis[p];
}
del[x]=,sz[x]=-;
for(i=last[x];i;i=e[i].pre)if(!del[e[i].too])
POI=sz[e[i].too],work(e[i].too,dep+);
} int main(){
n=read();
for(i=;i<=n;i++){
a[i]=read();
if(i>){
PRE=AFT=,V=a[i],getpre(rt),getaft(rt),
insert(rt);
if(!PRE||!AFT)ins(PRE|AFT,a[i]),u[PRE|AFT][PRE>]=;
else if(!u[PRE][])u[PRE][]=,ins(PRE,a[i]);
else u[AFT][]=,ins(AFT,a[i]);
}else V=a[i],insert(rt);
}
// for(i=1;i<=n;i++)for(j=last[i];j;j=e[j].pre)printf("%d-->%d\n",i,e[j].too); mx[]=<<,POI=n,work(a[],);ll ans=;int fa,son,dis;
for(i=;i<=n;i++){
k=a[i]; ans+=_sum[k],_sz[k]++;
for(j=mxdep[k]-;j;j--)
fa=bel[k][j],son=belson[k][j],dis=dist[k][j],
ans+=1ll*dis*(_sz[fa]-_sonsz[son])+_sum[fa]-_sonsum[son],
_sz[fa]++,_sonsz[son]++,_sum[fa]+=dis,_sonsum[son]+=dis; printf("%lld\n",ans);
}
}

[51nod1297]管理二叉树的更多相关文章

  1. 51nod 1297 管理二叉树

    一个初始为空的二叉搜索树T,以及1到N的一个排列P: {a1, a2, ..., aN}.我们向这个二叉搜索树T添加这些数,从a1开始, 接下来是 a2, ..., 以aN结束.在每一个添加操作后,输 ...

  2. 51 nod 1297 管理二叉树

    原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1297 先是暴力加优化T了最后两个点…… 我还是来想想正解吧. ...

  3. 四则运算(Java) 陈志海 邓宇

    目录 Github项目地址 PSP表格 功能要求 题目 功能(已全部实现) 效能分析 设计实现过程 数值生成 算式生成 问题集生成 设计实现过程 代码说明 测试运行 代码覆盖率 项目小结 Github ...

  4. Netty源码解析 -- PoolChunk实现原理(jemalloc 3的算法)

    前面文章已经分享了Netty如何实现jemalloc 4算法管理内存. 本文主要分享Netty 4.1.52之前版本中,PoolChunk如何使用jemalloc 3算法管理内存. 感兴趣的同学可以对 ...

  5. 深入C#内存管理来分析值类型&引用类型,装箱&拆箱,堆栈几个概念组合之间的区别

    C#初学者经常被问的几道辨析题,值类型与引用类型,装箱与拆箱,堆栈,这几个概念组合之间区别,看完此篇应该可以解惑. 俗话说,用思想编程的是文艺程序猿,用经验编程的是普通程序猿,用复制粘贴编程的是2B程 ...

  6. C语言实现二叉树-02版

    ---恢复内容开始--- 昨天,提交完我们的二叉树项目后,今天早上项目经理早早给我打电话: 他说,小伙子干的不错.但是为什么你上面的insert是recusive的呢? 你难道不知道万一数据量大啦!那 ...

  7. C++11 智能指针unique_ptr使用 -- 以排序二叉树为例

    用智能指针可以简化内存管理.以树为例,如果用普通指针,通常是在插入新节点时用new,在析构函数中调用delete:但有了unique_ptr类型的智能指针,就不需要在析构函数中delete了,因为当u ...

  8. linux内核分析之内存管理

    1.struct page /* Each physical page in the system has a struct page associated with * it to keep tra ...

  9. Android 内存管理(二)

    很多开发者都是从j2me或j2ee上过来的,对于内存的使用和理解并不是很到位,Android开发网本次给大家一些架构上的指导,防止出现豆腐渣工 程的出现.Android作为以Java语言为主的智能平台 ...

随机推荐

  1. 【java】控制台实现贪吃蛇小游戏-LinkedList、Scanner

    package com.myproj.snake; public class Node { private int i,j; public Node(){} public Node(int i, in ...

  2. Function:光标位置插入文本并且光标移动到最后

    //光标位置插入文本 function insertText(obj, str) { if(document.selection) { var sel = document.selection.cre ...

  3. [array] leetcode - 54. Spiral Matrix - Medium

    leetcode-54. Spiral Matrix - Medium descrition GGiven a matrix of m x n elements (m rows, n columns) ...

  4. Python 初体验

    2017的最后一天,在QC的谆谆教诲下,我终于写(背)了九道题,对Python的基本语法有了一个大致了解. 1.A+B+C 就是为了练输入,line=input().split()  录入列表,分割开 ...

  5. 两个HC-05蓝牙模块互相绑定构成无线串口模块

    HC-05 嵌入式蓝牙串口通讯模块(以下简称模块)具有两种工作模式:命令响应工作模式和自动连接工作模式,在自动连接工作模式下模块又可分为主(Master).从(Slave)和回环(Loopback)三 ...

  6. java中可变长参数

    ** * Created by Lenovo on 2017/12/10. * java中可变长参数 */ public class reflect04 { //m1有一个int类型的可比变长参数 / ...

  7. Git 企业开发者教程

      为什么要写这样一个面向企业开发者的Git教程?这个问题也困扰我自己很久.其实我使用git的时间也不短了,但是就和正在阅读本文的每一位一样,常用的基本就是那么几个(git clone, git pu ...

  8. golang sql database drivers

    https://github.com/golang/go/wiki/SQLDrivers SQL database drivers The database/sql and database/sql/ ...

  9. 视觉SLAM的方案总结

    MoNoSLAM:https://github.com/hanmekim/SceneLib2 以扩展卡尔曼滤波为后端,追踪前端非常稀疏的特征点,以相机的当前状态和所有路标点为状态量,更新其均值和协方差 ...

  10. 【转】java jvm 线程 与操作系统线程

    原文链接:http://segmentfault.com/q/1010000000370403 Java的目标是要跨平台,而不同的操作系统(如类Unix和Windows)其任务调度机制有很大的不同,故 ...