原题链接: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. 王者齐聚!Unite 2017 Shanghai 日程讲师全揭晓

    汇聚了来自全球的 Unity开发者.发行商.培训家及爱好者的 Unite 2017 Shanghai 即将于于 5 月 11 日-13日在上海·国际会议中心隆重举行.Unite 大会是由 Unity ...

  2. lua的通用print函数

    1.前言 最近在做关于openresty方面的工作,涉及到lua脚本语言,经常需要打日志查看内容.普通的print函数遇到nil或table时,非常无力.而项目中的代码经常遇到参数为nil或table ...

  3. ArcGIS API for JavaScript 4.2学习笔记[26] 缓冲区分析【基于geometryEngine工具类】

    要说GIS空间分析最经典的例子,就是缓冲区分析了. 本例使用geometryEngine来绘制缓冲区环.因为官方给的例子有3D和2D场景,所以就会显得比较复杂. 当鼠标在视图上点击时,就会生成一个缓冲 ...

  4. 配置linux下apache跨域问题

    1.apache设置允许远程访问 打开FTP,登录服务器,找到etc文件夹下的httpd.conf文件,然后下载到本地 打开本地httpd.conf文件夹,找到对应的端口ip地址,修改如下 <V ...

  5. Oracle学习笔记_10_判断是否为日期类型

    FUNCTION isdate (datestr VARCHAR2, format VARCHAR2) RETURN number IS p_date DATE; BEGIN SELECT TO_DA ...

  6. Bilateral Filter

    最近在看图像风格化的论文的时候,频繁遇到 Bilateral Filter.google 一波后,发现并不是什么不得了的东西,但它的思想却很有借鉴意义. 简介 Bilateral Filter,中文又 ...

  7. 为clang添加中文关键字

    原址: https://zhuanlan.zhihu.com/p/31158537 以clang为基础做了一个与C++.C兼容中英文关键字的编译器 swizl/cnlang 原理就是加与英文关键字等效 ...

  8. git上传文件到github

     一.git之上传代码到github. 安装git,这个就不说了,很多帖子都有详细说明.  二.新建仓库,GitHub上的,首先申请账号.  三.本地选择地方新建本地仓库. 建完本地仓库文件夹,在本地 ...

  9. MicroPython教程之TPYBoard开发板DIY小型家庭气象站

    众所周知,iPhone6/6Plus内置气压传感器,不过大家对于气压传感器还是很陌生.跟字面的意思一样,气压传感器就是用来测量气压的,但测量气压对于普通的手机用户来说又有什么作用呢? 海拔高度测量 对 ...

  10. TensorFlow实现knn(k近邻)算法

    首先先介绍一下knn的基本原理: KNN是通过计算不同特征值之间的距离进行分类. 整体的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于 ...