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 ...
随机推荐
- apt-get 的常用使用说明
API神命令: apt-get -h >>help.txt apt 1.0.10.2ubuntu1,用于 amd64 体系结构,编译于 Oct 5 2015 15:55:05用法: apt ...
- ubuntu基本配置
新系统装好后的操作: 1.resource updata:服务器镜像地址选择 2.删除不必要软件: 2.1:libreoffice sudo apt-get remove libreoffice-co ...
- 了解 C++ 默默编写并调用的函数
前言 对于一个类来说,最最基础的三类成员函数莫过于:构造函数,析构函数以及拷贝函数 (copy构造函数和=重载函数).即使你的类没有为这些函数做出定义,C++ 也会自动为你创建.本文将讲述的是 C++ ...
- db2 存储过程 语法 及结果集查询
第一次用存储过程,关于处理待办的,不知道怎么执行和传参数 给存储过程 ,其实就一句话很简单. @call PRC_MISSIONLIST_QUERY('27020214', '27040000', ' ...
- c 函数及指针学习 10
标准库函数 1算数运算stdlib.h 2随机数stdlib.h 3字符串转化stdlib.h 4数学函数 math.h 5日期和时间 time.h 6信号 signal.h 7打印可变参数列表std ...
- JavaWeb学习记录(十五)——浏览器Cookie禁用后的处理
IE禁用Cookie方式:
- ZOJ-3933 Team Formation (二分图最佳完美匹配)
题目大意:n个人,分为两个阵营.现在要组成由若干支队伍,每支队伍由两个人组成并且这两个人必须来自不同的阵营.同时,每个人都有m个厌恶的对象,并且厌恶是相互的.相互厌恶的人不能组成一支队伍.问最多能组成 ...
- js获取客户端操作系统
function detectOS() { var sUserAgent = navigator.userAgent; var isWin = (navigator.platform == " ...
- C++ 遇到的问题小结
1. cannot convert 'std::basic_string<char>' to 'int' in assignment ... 原始code如下: int id2; std: ...
- 【Unity3D技巧】一个简单的Unity-UI框架的实现
如何使用 请直接导入UnityUIFramework这个UnityPackage,然后进入名为Test的Scene即可开始体验各种特性,Enjoy!你可以通过访问我的Github进行查阅和下载. Vi ...