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 ...
随机推荐
- (理论篇)53个要点提高PHP编程效率
用单引号代替双引号来包含字符串,这样做会更快一些.因为php会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的"函数"( ...
- 147. Insertion Sort List
Sort a linked list using insertion sort. 代码如下: /** * Definition for singly-linked list. * public cla ...
- 2015GitWebRTC编译实录9
2015.07.20 neteq 编译通过注意不要引用tools目录里的内容 [1347/1600 ] CXX obj /webrtc/modules/audio_coding/neteq/neteq ...
- jni数据传递——会不断的更新,测试没有问题,再整理进来。
工作中遇到了ndk编程,其实核心就是java和本地的数据交互.现把所有数据类型的传递写成demo. 1,ini数组传递 我们实现传递8个数值过去,然后本地将八个数值放到数组,返回. java代码: ...
- ListView滚动到顶部
videoAdapter.notifyDataSetChanged();videoListView.setSelection(0); 注意顺序先notify后setSelection
- C#部分---arraylist集合、arraylist集合中的object数据转换成int类string类等;间隔时间的表示方法;
ArrayList和Array的区别: 相同点:1.两者都实现了IList.ICollection.IEnumerable接口: 2.两者都可以使用证书索引访问集合中的元素,包括读取和赋值 ...
- UVa 1592 数据库(c++pair)
Input Input contains several datasets. The first line of each dataset contains two integer numbersn ...
- codeforces 725/C
Hidden Word time limit per test 2 seconds memory limit per test 256 megabytes input standard input o ...
- 附录三 嵌入式C程序的编译与调试
课程回顾 C语言库的特性和发展 C语言库的常用库函数 标准库函数的特色应用 git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysi ...
- [CTSC 2012][BZOJ 2806]Cheat
真是一道好题喵~ 果然自动机什么的就是要和 dp 搞基才是王道有木有! A:连 CTSC 都叫我们搞基,果然身为一个程序猿,加入 FFF 团是我此生最明智的选择.妹子什么闪边去,大家一起来搞基吧! Q ...