[51nod1297]管理二叉树
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]管理二叉树的更多相关文章
- 51nod 1297 管理二叉树
一个初始为空的二叉搜索树T,以及1到N的一个排列P: {a1, a2, ..., aN}.我们向这个二叉搜索树T添加这些数,从a1开始, 接下来是 a2, ..., 以aN结束.在每一个添加操作后,输 ...
- 51 nod 1297 管理二叉树
原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1297 先是暴力加优化T了最后两个点…… 我还是来想想正解吧. ...
- 四则运算(Java) 陈志海 邓宇
目录 Github项目地址 PSP表格 功能要求 题目 功能(已全部实现) 效能分析 设计实现过程 数值生成 算式生成 问题集生成 设计实现过程 代码说明 测试运行 代码覆盖率 项目小结 Github ...
- Netty源码解析 -- PoolChunk实现原理(jemalloc 3的算法)
前面文章已经分享了Netty如何实现jemalloc 4算法管理内存. 本文主要分享Netty 4.1.52之前版本中,PoolChunk如何使用jemalloc 3算法管理内存. 感兴趣的同学可以对 ...
- 深入C#内存管理来分析值类型&引用类型,装箱&拆箱,堆栈几个概念组合之间的区别
C#初学者经常被问的几道辨析题,值类型与引用类型,装箱与拆箱,堆栈,这几个概念组合之间区别,看完此篇应该可以解惑. 俗话说,用思想编程的是文艺程序猿,用经验编程的是普通程序猿,用复制粘贴编程的是2B程 ...
- C语言实现二叉树-02版
---恢复内容开始--- 昨天,提交完我们的二叉树项目后,今天早上项目经理早早给我打电话: 他说,小伙子干的不错.但是为什么你上面的insert是recusive的呢? 你难道不知道万一数据量大啦!那 ...
- C++11 智能指针unique_ptr使用 -- 以排序二叉树为例
用智能指针可以简化内存管理.以树为例,如果用普通指针,通常是在插入新节点时用new,在析构函数中调用delete:但有了unique_ptr类型的智能指针,就不需要在析构函数中delete了,因为当u ...
- linux内核分析之内存管理
1.struct page /* Each physical page in the system has a struct page associated with * it to keep tra ...
- Android 内存管理(二)
很多开发者都是从j2me或j2ee上过来的,对于内存的使用和理解并不是很到位,Android开发网本次给大家一些架构上的指导,防止出现豆腐渣工 程的出现.Android作为以Java语言为主的智能平台 ...
随机推荐
- 栈和队列数据结构的相互实现[LeetCode]
栈是先进后出,队列是先进后出,这里讨论一下两种数据结构之间的相互实现. 一.用两个栈实现队列 我们用一个栈来实现队列的进队操作(栈A),用另一个栈来实现队列的出队操作(栈B). 1.入队列: 把元素放 ...
- bzoj 4444: [Scoi2015]国旗计划
Description A国正在开展一项伟大的计划--国旗计划.这项计划的内容是边防战士手举国旗环绕边境线奔袭一圈.这 项计划需要多名边防战士以接力的形式共同完成,为此,国土安全局已经挑选了N名优秀的 ...
- ES6 函数的扩展1
1. 函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,为了避免这个问题,通常需要先判断一下参数y是否被赋值,如果没有,再等于默认值. ES6允许为函数的参数设置默认值,即直接 ...
- Golang fmt包使用小技巧
h1 { margin-top: 0.6cm; margin-bottom: 0.58cm; direction: ltr; color: #000000; line-height: 200%; te ...
- Nodejs使用redis
安装方法 安装redis方法请自行百度, 用npm方法,安装nodejs的redis模块 npm install redis 实战 var redis = require("redis&qu ...
- 万能选项卡,tab选项卡
//万能选项卡 function PaPtabs(thisObj, num) { if (thisObj.className == "active") return; var ta ...
- Spring之DAO二
上一篇算是把JdbcDaoSupport的使用演示了一下,这篇主要是演示MappingSqlQuery.SqlUpdate.SqlFunction的使用以及Spring的事务管理. 一.Mapping ...
- 进程管理工具htop/glances/dstat的使用
进程管理工具htop/glances/dstat的使用 Linux中进程的相关知识 1.什么是进程呢? 通俗的来说进程是运行起来的程序.唯一标示进程的是进程描述符(PID). 2.进程的分类 1)根据 ...
- SpringMVC RequestMapping注解
1.@RequestMapping 除了修饰方法,还可以修饰类 2.类定义处:提供初步的请求映射信息.相对于WEB应用的根目录 方法处:提供进一步细分映射信息 相对于类定义处的URL.若类定义处未 ...
- TreeMap 源码分析
简介 TreeMap最早出现在JDK 1.2中,是 Java 集合框架中比较重要一个的实现.TreeMap 底层基于红黑树实现,可保证在log(n)时间复杂度内完成 containsKey.get.p ...