原题链接: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 管理二叉树的更多相关文章

  1. 51nod 1297 管理二叉树

    一个初始为空的二叉搜索树T,以及1到N的一个排列P: {a1, a2, ..., aN}.我们向这个二叉搜索树T添加这些数,从a1开始, 接下来是 a2, ..., 以aN结束.在每一个添加操作后,输 ...

  2. 51 nod 1439 互质对(Moblus容斥)

    1439 互质对 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 有n个数字,a[1],a[2],…,a[n].有一个集合,刚开 ...

  3. 51 nod 1495 中国好区间

    1495 中国好区间 基准时间限制:0.7 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   阿尔法在玩一个游戏,阿尔法给出了一个长度为n的序列,他认为,一段好的区间,它的长度是& ...

  4. 51 nod 1427 文明 (并查集 + 树的直径)

    1427 文明 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题   安德鲁在玩一个叫“文明”的游戏.大妈正在帮助他. 这个游 ...

  5. 51 nod 1055 最长等差数列(dp)

    1055 最长等差数列 基准时间限制:2 秒 空间限制:262144 KB 分值: 80 难度:5级算法题 N个不同的正整数,找出由这些数组成的最长的等差数列.     例如:1 3 5 6 8 9 ...

  6. 51 nod 1421 最大MOD值

    1421 最大MOD值 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个a数组,里面有n个整数.现在要从中找到两个数字(可以 ...

  7. 51 nod 1681 公共祖先 (主席树+dfs序)

    1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另 ...

  8. 51 nod 1766 树上的最远点对(线段树+lca)

    1766 树上的最远点对 基准时间限制:3 秒 空间限制:524288 KB 分值: 80 难度:5级算法题   n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个 ...

  9. 51 nod 1405 树的距离之和

    1405 树的距离之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题   给定一棵无根树,假设它有n个节点,节点编号从1到n, 求任意两点之间的距离(最短路径)之 ...

随机推荐

  1. 用python在excel中读取与生成随机数写入excel中

    今天是我第一次发博客,就关于python在excel中的应用作为我的第一篇吧. 具体要求是:在一份已知的excel表格中读取学生的学号与姓名,再将这些数据放到新的excel表中的第一列与第二列,最后再 ...

  2. Nodejs的运行原理-架构篇

    前言 本来是想只做一个Nodejs运行原理-科普篇,但是收到了不少私信,要我多分享一些更进阶,更详细的内容,所以我会在接下来的两个月里继续更新Nodejs运行原理. PS:此系列只做Nodejs的运行 ...

  3. 在QLabel上同时显示文字和图片的方法

    有两种方法. 1.打开UI文件,在界面右键单击QLabel对象,选改变多信息文本 选择图片再确定,左侧问号就是图片. 2.直接在QLabel写富文本 <html><head/> ...

  4. python 小脚本升级-- 钉钉群聊天机器人

    一则小脚本(工作中用) 在这篇文章中写的监控的脚本,发送监控的时候 是利用的邮箱,其实在实际,邮箱查收有着不方便性,于是乎升级, 我们工作中,经常用钉钉,那么如果要是能用到钉钉多好,这样我们的监控成功 ...

  5. vim置于后台,vim 编辑多文件

    这里介绍一个很实用的方法:1.将vim置于后台,直接按 ctrl + z可以将当前的vim置于后台 2.然后可以去别的目录再打开一个 当你需要打开之前的vim的时候3.打jobs命令看当前有哪些vim ...

  6. composer安装laravel

    安装composer composer是一个很有用的工具,我将用它在本机(win7)上安装laravel 到composer的官网,根据自己的系统要求下载相应的版本 安装laravel 首先cmd下进 ...

  7. PCoA主坐标分析

    来源:http://blog.sina.com.cn/s/blog_670445240101nlss.html 1   背景介绍 这是一种排序方法.假设我们对N个样方有了衡量它们之间差异即距离的数据, ...

  8. StringMVC @RequestMapping method属性

    @RequestMapping(value="/testMethod",method=RequestMethod.POST) public String testMethod(){ ...

  9. PXE+kickstart网络安装CentOS7.4系统及过程中各种报错

    环境:关闭防火墙.selinux 注意:虚拟机进行网络安装的话,7.3以后的系统是需要2G以上的内存 [root@kickstart ~]# cat /etc/redhat-release CentO ...

  10. 第二章:Python基础の快速认识基本数据类型和操作实战

    本课主题 字符串和操作实战 二进制操作实战 List 列表和操作实战 Tuple 元組和操作实战 Dict 字典和操作实战 作業需求 引言 这遍文章简单介绍了 Python 字符串和集合的方法和应用, ...