51 nod 1297 管理二叉树
原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1297
先是暴力加优化T了最后两个点……
我还是来想想正解吧。
先写棵线段树把二叉搜索树建出来,然后在树上做下点分治就好了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lp (p<<1)
#define rp ((p<<1)|1)
using namespace std; int read_p,read_ca;
inline int read(){
read_p=;read_ca=getchar();
while(read_ca<''||read_ca>'') read_ca=getchar();
while(read_ca>=''&&read_ca<='') read_p=read_p*+read_ca-,read_ca=getchar();
return read_p;
}
struct na{int y,z,ne,k;}b[],B[];
int n,m,a[],x,y,l[],num=,de[],L[],Num=,s[],Si,ro,ma;
bool bo[];
long long mmh[][],S[][];
long long MMH=;
inline void in(int x,int y){b[++num].y=y;b[num].ne=l[x];l[x]=num;}
inline void In(int x,int y,int z,int k){B[++Num].y=y;B[Num].z=z;B[Num].k=k;B[Num].ne=L[x];L[x]=Num;}
struct tree{int ma,mi;}t[];
void add(int p,int l,int r,int v){
if (a[t[p].ma]<a[v]||t[p].ma==) t[p].ma=v;
if (a[t[p].mi]>a[v]||t[p].mi==) t[p].mi=v;
if (l==r) return;
int mid=l+r>>;
if (a[v]<=mid) add(lp,l,mid,v);else add(rp,mid+,r,v);
}
int quea(int p,int l,int r,int R){
if (R>=r) return t[p].ma;
int mid=l+r>>;
if (R<=mid) return quea(lp,l,mid,R);else if (mid=quea(rp,mid+,r,R)) return mid;else return t[lp].ma;
}
int quei(int p,int l,int r,int R){
if (R<=l) return t[p].mi;
int mid=l+r>>;
if (R>mid) return quei(rp,mid+,r,R);else if (mid=quei(lp,l,mid,R)) return mid;else return t[rp].mi;
}
void gs(int x,int f){
s[x]=;
int u=;
for (register int i=l[x];i;i=b[i].ne)
if (b[i].y!=f&&!bo[b[i].y]){
gs(b[i].y,x);
s[x]+=s[b[i].y];
if (u<s[b[i].y]) u=s[b[i].y];
}
if (Si-s[x]>u) u=Si-s[x];
if (u<ma) ma=u,ro=x;
}
void dfs(int x,int f,int r,int z,int k){
s[x]=;
In(x,r,z,k);
for (register int i=l[x];i;i=b[i].ne)
if (!bo[b[i].y]&&b[i].y!=f) dfs(b[i].y,x,r,z+,k),s[x]+=s[b[i].y];
}
void work(int x,int S){
Si=S;ma=1e9;gs(x,);bo[x=ro]=;
int u=;
for (register int i=l[x];i;i=b[i].ne) if (!bo[b[i].y]) dfs(b[i].y,x,x,,++u);In(x,x,,++u);
for (register int i=l[x];i;i=b[i].ne) if (!bo[b[i].y]) work(b[i].y,s[b[i].y]);
}
int main(){
register int i,j;
n=read();a[n+]=n+;add(,,n+,);add(,,n+,n+);
a[]=read();add(,,n+,);de[]=;
for (i=;i<=n;i++){
a[i]=read();
x=quea(,,n+,a[i]-);y=quei(,,n+,a[i]+);
if (de[x]>de[y]){
in(x,i);
in(i,x);
de[i]=de[x]+;
}else{
in(y,i);
in(i,y);
de[i]=de[y]+;
}
add(,,n+,i);
}
work(,n);
for (i=;i<=n;i++){
for (j=L[i];j;j=B[j].ne) MMH+=1LL*B[j].z*(S[B[j].y][]-S[B[j].y][B[j].k])+mmh[B[j].y][]-mmh[B[j].y][B[j].k],
mmh[B[j].y][]+=B[j].z,mmh[B[j].y][B[j].k]+=B[j].z,S[B[j].y][]++,S[B[j].y][B[j].k]++;
printf("%lld\n",MMH);
}
}
51 nod 1297 管理二叉树的更多相关文章
- 51nod 1297 管理二叉树
一个初始为空的二叉搜索树T,以及1到N的一个排列P: {a1, a2, ..., aN}.我们向这个二叉搜索树T添加这些数,从a1开始, 接下来是 a2, ..., 以aN结束.在每一个添加操作后,输 ...
- 51 nod 1439 互质对(Moblus容斥)
1439 互质对 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 有n个数字,a[1],a[2],…,a[n].有一个集合,刚开 ...
- 51 nod 1495 中国好区间
1495 中国好区间 基准时间限制:0.7 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 阿尔法在玩一个游戏,阿尔法给出了一个长度为n的序列,他认为,一段好的区间,它的长度是& ...
- 51 nod 1427 文明 (并查集 + 树的直径)
1427 文明 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 安德鲁在玩一个叫“文明”的游戏.大妈正在帮助他. 这个游 ...
- 51 nod 1055 最长等差数列(dp)
1055 最长等差数列 基准时间限制:2 秒 空间限制:262144 KB 分值: 80 难度:5级算法题 N个不同的正整数,找出由这些数组成的最长的等差数列. 例如:1 3 5 6 8 9 ...
- 51 nod 1421 最大MOD值
1421 最大MOD值 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个a数组,里面有n个整数.现在要从中找到两个数字(可以 ...
- 51 nod 1681 公共祖先 (主席树+dfs序)
1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另 ...
- 51 nod 1766 树上的最远点对(线段树+lca)
1766 树上的最远点对 基准时间限制:3 秒 空间限制:524288 KB 分值: 80 难度:5级算法题 n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个 ...
- 51 nod 1405 树的距离之和
1405 树的距离之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 给定一棵无根树,假设它有n个节点,节点编号从1到n, 求任意两点之间的距离(最短路径)之 ...
随机推荐
- Mac中Eclipse安装和使用svn
Eclipse版本为Neon Release (4.6.0) 安装svn 安装HomeBrew 在终端中输入 ruby -e "$(curl -fsSL https://raw.github ...
- 为了CET-4!
Directions For tiis part,you are allowed 30 minutes to write an essay.Suppose there are two options ...
- android中的五大布局(控件的容器,可以放button等控件)
一.android中五大布局相当于是容器,这些容器里可以放控件也可以放另一个容器,子控件和布局都需要制定属性. 1.相对布局:RelativeLayout @1控件默认堆叠排列,需要制定控件的相对位置 ...
- Cat 客户端如何构建调用链消息树
场景 & 代码 Inner0 中的某方法调用了 Inner1,代码 Inner1的代码很简单, Cat通过一个线程本地变量来保存调用链的相关信息,其中核心的数据结构是消息树和操作栈.消息树用来 ...
- 重写JS的鼠标右键点击菜单
重写JS的鼠标右键点击菜单 该效果主要有三点,一是对重写的下拉菜单的隐藏和显示:二是屏蔽默认的鼠标右键事件:三是鼠标左键点击页面下拉菜单隐藏. 不多说,上html代码: 1 <ul id=&qu ...
- w 命令详解
作用: 用于显示已经登录系统的用户列表, 并显示用户正在执行的指令. 执行这个命令可得知目前登入系统的用户有哪些人, 以及他们正在执行的程序. 单独执行w 命令会显示所有的用户, 您也可指定用户名称 ...
- golang社区
a development list for Go Programming Language https://groups.google.com/forum/#!forum/golang-dev a ...
- 开发中关于Git那些事(续:Git变基)
其实上一篇写的内容仅仅是Git的冰山一角,如果你认为Git就是简简单单的几行命令,那只能说明你还没有真正了解Git这个强大的内容寻址文件系统.这篇文章,还是接着介绍一些实用但是很少有人知晓的一些命令, ...
- CSS3 自定义动画(animation)
除了在之前的文章中介绍过的 CSS3 的变形 (transformation) 和转换 (transition) 外,CSS3 还有一种自由度更大的自定义动画,开发者甚至可以使用变形(transfor ...
- asp.net core webapi 服务端配置跨域
在前后端分离开发中服务端仅仅只为前端提供api接口,并且前后端往往单独部署,此时就会出现浏览器跨域问题.asp.net core提供了简单优雅的解决方案. 在startup文件的Configure添加 ...