51nod 1297 管理二叉树
一个初始为空的二叉搜索树T,以及1到N的一个排列P: {a1, a2, ..., aN}。我们向这个二叉搜索树T添加这些数,从a1开始, 接下来是 a2, ..., 以aN结束。在每一个添加操作后,输出T上每对节点之间的距离之和。
第1行:1个数N。(1 <= N <= 100000)
第2 - N + 1行:每行1个数,对应排列的元素。(1 <= ai <= N)
输出共N行,每行1个数,对应添加当前元素后,每对节点之间的距离之和。
用set维护一下空的左右孩子位置和已插入的点可以O(nlogn)建树
读入优化t了4个点,读入+输出优化t了1个点,fread+fwrite才a。。
#include<stdio.h>
#include<set>
#include<cmath>
const int N=;
char buf[],*ptr=buf,rbuf[],*rptr=rbuf-;
inline int _(){
int x=,c=*++rptr;
while(c<)c=*++rptr;
while(c>)x=x*+c-,c=*++rptr;
return x;
}
inline void _(long long x){
static int stk[],stp=;
if(!x)stk[stp++]=;
while(x)stk[stp++]=x%,x/=;
while(stp)*ptr++=stk[--stp]+;
*ptr++=;
}
int n,pv=;
std::set<int>le,re,in;
int ch[N][],xs[N],dep[N],fa[N],sz[N],pf[N],top[N];
long long F1[N],F2[N],ans=,ANS[N];
int _sz[N],h[N],tp[N];
inline int dis(int x,int y){
int a=top[x],b=top[y],s=dep[x]+dep[y];
while(a!=b){
if(dep[a]<dep[b])y=fa[b],b=top[y];
else x=fa[a],a=top[x];
}
s-=dep[dep[x]<dep[y]?x:y]<<;
return s;
}
void rebuild(){
ans=;
for(int i=pv-;~i;--i){
int w=xs[i],lc=ch[w][],rc=ch[w][];
h[w]=;
_sz[w]=+_sz[lc]+_sz[rc];
F1[w]=_sz[w]-+F1[lc]+F1[rc];
}
for(int i=;i<pv;++i){
int w=xs[i],lc=ch[w][],rc=ch[w][],s=_sz[rc]-_sz[lc];
F2[lc]=pv+s+F2[w]+F1[rc];
F2[rc]=pv-s+F2[w]+F1[lc];
F1[w]+=F2[w];
ans+=F1[w];
}
ans>>=;
}
int main(){
rbuf[fread(rbuf,,,stdin)]=;
n=_();
xs[]=_();
le.insert(xs[]);
re.insert(xs[]);
in.insert(xs[]);
for(int i=;i<n;++i){
int x=xs[i]=_();
in.insert(x);
auto it=le.upper_bound(x);
if(it!=le.end()){
auto it2=in.upper_bound(x);
if(it2!=in.end()&&*it2==*it){
ch[fa[x]=*it][]=x;
le.erase(it);
le.insert(x),re.insert(x);
continue;
}
}
it=re.upper_bound(x);
--it;
ch[fa[x]=*it][]=x;
re.erase(it);
le.insert(x),re.insert(x);
}
for(int i=;i<n;++i){
int w=xs[i];
dep[w]=dep[fa[w]]+;
}
for(int i=n-;~i;--i){
int w=xs[i];
int sl=sz[ch[w][]],sr=sz[ch[w][]];
sz[w]=+sl+sr;
pf[w]=ch[w][sl<sr];
}
for(int i=;i<n;i++){
int w=xs[i];
if(!top[w])for(int u=w;u;u=pf[u])top[u]=w;
}
int B=std::sqrt(n)/1.2+;
for(int i=;i<n;++i){
int w=xs[i],f=fa[w];
tp[w]=h[f]?tp[f]:f;
h[w]=h[f]+;
ans+=h[w]*pv+F1[tp[w]];
for(int j=pv;j<i;j++)ans+=dis(w,xs[j]);
ANS[i]=ans;
if(i%B==B-){
pv=i+;
rebuild();
}
}
for(int i=;i<n;++i)_(ANS[i]);
fwrite(buf,,ptr-buf,stdout);
return ;
}
51nod 1297 管理二叉树的更多相关文章
- 51 nod 1297 管理二叉树
原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1297 先是暴力加优化T了最后两个点…… 我还是来想想正解吧. ...
- [51nod1297]管理二叉树
一个初始为空的二叉搜索树T,以及1到N的一个排列P: {a1, a2, ..., aN}.我们向这个二叉搜索树T添加这些数,从a1开始, 接下来是 a2, ..., 以aN结束.在每一个添加操作后,输 ...
- 51nod 1297
思路: 搞个栈模拟一下,也才5w; 直接wa1了..然后想到井口如果都进不去那就...一定GG了. 所以维护一下从井口到井底是非递增的就好了: #include <cstdio> #inc ...
- 四则运算(Java) 陈志海 邓宇
目录 Github项目地址 PSP表格 功能要求 题目 功能(已全部实现) 效能分析 设计实现过程 数值生成 算式生成 问题集生成 设计实现过程 代码说明 测试运行 代码覆盖率 项目小结 Github ...
- Netty源码解析 -- PoolChunk实现原理(jemalloc 3的算法)
前面文章已经分享了Netty如何实现jemalloc 4算法管理内存. 本文主要分享Netty 4.1.52之前版本中,PoolChunk如何使用jemalloc 3算法管理内存. 感兴趣的同学可以对 ...
- 51nod 1832 先序遍历与后序遍历【二叉树+高精度】
题目链接:51nod 1832 先序遍历与后序遍历 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 对于给定的一个二叉树的先序遍历和后序遍历,输出有多少种满足条件的 ...
- 深入C#内存管理来分析值类型&引用类型,装箱&拆箱,堆栈几个概念组合之间的区别
C#初学者经常被问的几道辨析题,值类型与引用类型,装箱与拆箱,堆栈,这几个概念组合之间区别,看完此篇应该可以解惑. 俗话说,用思想编程的是文艺程序猿,用经验编程的是普通程序猿,用复制粘贴编程的是2B程 ...
- C语言实现二叉树-02版
---恢复内容开始--- 昨天,提交完我们的二叉树项目后,今天早上项目经理早早给我打电话: 他说,小伙子干的不错.但是为什么你上面的insert是recusive的呢? 你难道不知道万一数据量大啦!那 ...
- C++11 智能指针unique_ptr使用 -- 以排序二叉树为例
用智能指针可以简化内存管理.以树为例,如果用普通指针,通常是在插入新节点时用new,在析构函数中调用delete:但有了unique_ptr类型的智能指针,就不需要在析构函数中delete了,因为当u ...
随机推荐
- 哎哟,我的.NET呀
今早无意看到一篇文章,看着.Net被喷得越来越惨,终于还是有人忍不住要奋起反抗了哇! 虽然我已经转了java(大致方向)(没想到我是转的java方向!)好吧!其实也不算是转,就像文章所说的,我最多算是 ...
- mapreduce入门之wordcount注释详解
mapreduce版本:0.2.0之前 说明: 该注释为之前学习时找到的一篇,现在只是在入门以后对该注释做了一些修正以及添加. 由于版本问题,该代码并没有在集群环境中运行,只将其做为理解mapredu ...
- POJ 2253 Frogger
题目链接:http://poj.org/problem?id=2253 Frogger Time Limit: 1000MS Memory Limit: 65536K Total Submissi ...
- 2015GitWebRTC编译实录5
2015.07.20 libaudio_encoder_interface/libaudio_decoder_interface 编译通过将encoder,decoder两个lib合并了,后面需要看看 ...
- code::blocks的快捷键汇总
编辑部分: Ctrl + A:全选 Ctrl + C:复制 Ctrl + X: 剪切 Ctrl + V:粘贴 Ctrl + Z:撤销 Ctrl + S:保存 Ctrl + Y / Ctrl + S ...
- C#笔记 -----扩展方法
在我们使用vs自带的工具函数时,如: string str='111';str.toInt(); 有没有想到过他们是怎么来的? 这就是C# 的 方法扩展: age: using system: pu ...
- Codeforces Round #141 (Div. 2)
A. Is your horseshoe on the other hoof? 模拟题意. B. Two Tables 暴力枚举\(x,y\). C. Fractal Detector 显然,判断图形 ...
- Javascript高性能动画与页面渲染
转自:http://www.infoq.com/cn/articles/javascript-high-performance-animation-and-page-rendering No setT ...
- 使用SSH密钥连接Github
使用Github,也许大家觉得比较麻烦的就是在每次push的时候,都需要输入用户名和密码.如果使用SSH,就可以记住用户名,并创建属于自己 的密码来保证安全操作,还有神奇的一招可以“不用输入密码”哦. ...
- android屏幕亮度
/** * 获得当前屏幕亮度的模式 * SCREEN_BRIGHTNESS_MODE_AUTOMATIC=1 为自动调节屏幕亮度 * SCREEN_BRIGHTNESS_MODE_MANUAL=0 为 ...