题目链接:https://cn.vjudge.net/contest/287725#problem/B

题目大意:现在有一棵二叉树,所有非叶子节点都有两个孩子。在每个叶子节点上有一个权值(有n个叶子节点,满足这些权值为1..n的一个排列)。可以任意交换每个非叶子节点的左右孩子。
要求进行一系列交换,使得最终所有叶子节点的权值按照遍历序写出来,逆序对个数最少。

具体思路:首先说一下对逆序对的处理。2431的逆序数是4((2,1),(4,3),(4,3),(3,1))。但是两个for循环处理肯定是不行的,我们可以通过线段树来求出逆序对数,每插入一个数,就先判断一个这个数在线段树上后面有多少个数就可以了。

第一次插入2,后面没有数,此时逆序对数为0。

第二次插入4,后面没有数,此时的逆序对数为0.

第三次插入3,后面有2这个数,此时的逆序对数为1。

第四次插入1,后米娜有2,3,4这三个数,此时的逆序对数为1+3=4。

然后再就是对于题目中所说的交换操作了。在线段树中每一个节点的逆序对数等于这个节点的左孩子的逆序对数+右孩子的逆序对数+后面的树中的逆序对数

如果是交换当期节点的左右孩子,当前这个点的逆序对数等于左孩子中大于等于当当前节点值的个数*右孩子中小于等于当前节点值的个数。

如果不交换的话,当前这个点的逆序对数等于左孩子中小于等于当前节点值的个数*右孩子中小于等于当前节点值的个数。

ch数组代表的是当前这个节点在初始二叉树中左孩子和右孩子的编号。

cont代表的数当前在线段树上的编号的贡献

le代表的是当前节点左孩子在线段树的编号

ri代表的是当前节点右孩子在线段树的编号

AC代码:

 #include<bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 4e6+;
const int mod =1e6;
# define LL_inf 0x3f3f3f3f3f3f3f
ll n,root,ans,t1,t2;
ll num1,num2;
ll ch[maxn][];
ll cont[maxn];
ll le[maxn],ri[maxn],father[maxn];
void up(ll x){
cont[x]=cont[le[x]]+cont[ri[x]];
}
void update(ll &x,ll val,ll l,ll r){
if(!x)x=++num2;//如果之前出现过就不需要在新建节点了
if(l==r){
cont[x]=;
return ;
}
ll mid=l+r>>;
if(val<=mid)update(le[x],val,l,mid);
else update(ri[x],val,mid+,r);
up(x);
}
void dfs(ll &x){
x=++num1;
ll tmp;
scanf("%lld",&tmp);
if(!tmp){
dfs(ch[x][]);
dfs(ch[x][]);
}
else update(father[x],tmp,,n);
}
ll emerge(ll u,ll v){
if(!u)return v;
if(!v)return u;
t1+=(cont[le[u]]*cont[ri[v]]);
t2+=(cont[le[v]]*cont[ri[u]]);
le[u]=emerge(le[u],le[v]);
ri[u]=emerge(ri[u],ri[v]);
up(u);
return u;
}
void solve(ll x){
if(!ch[x][])return ;
solve(ch[x][]);
solve(ch[x][]);
t1=,t2=;
father[x]=emerge(father[ch[x][]],father[ch[x][]]);//注意这个是father
ans+=min(t1,t2);
}
int main(){
scanf("%lld",&n);
dfs(root);
solve(root);
printf("%lld\n",ans);
}

B - Tree Rotations HYSBZ - 2212 (线段树合并)的更多相关文章

  1. 【bzoj2212】[Poi2011]Tree Rotations 权值线段树合并

    原文地址:http://www.cnblogs.com/GXZlegend/p/6826614.html 题目描述 Byteasar the gardener is growing a rare tr ...

  2. 【bzoj1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+权值线段树合并

    题目描述 求一张图的严格次小生成树的边权和,保证存在. 输入 第一行包含两个整数N 和M,表示无向图的点数与边数. 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z ...

  3. [学习笔记]dsu on a tree(如何远离线段树合并)

    https://www.zybuluo.com/ysner/note/1318613 背景 这玩意来源于一种有局限性的算法. 有一种广为人知的,树上离线维护子树信息的做法. (可以参照luogu360 ...

  4. [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】

    题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...

  5. bzoj 2212 : [Poi2011]Tree Rotations (线段树合并)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2212 思路:用线段树合并求出交换左右儿子之前之后逆序对的数量,如果数量变小则交换. 实现 ...

  6. BZOJ.2212.[POI2011]Tree Rotations(线段树合并)

    题目链接 \(Description\) 给定一棵n个叶子的二叉树,每个叶节点有权值(1<=ai<=n).可以任意的交换两棵子树.问最后顺序遍历树得到的叶子权值序列中,最少的逆序对数是多少 ...

  7. 【BZOJ2212】[Poi2011]Tree Rotations 线段树合并

    [BZOJ2212][Poi2011]Tree Rotations Description Byteasar the gardener is growing a rare tree called Ro ...

  8. bzoj2212[Poi2011]Tree Rotations [线段树合并]

    题面 bzoj ans = 两子树ans + min(左子在前逆序对数, 右子在前逆序对数) 线段树合并 #include <cstdio> #include <cstdlib> ...

  9. 【BZOJ2212】[POI2011]Tree Rotations (线段树合并)

    题解: 傻逼题 启发式合并线段树里面查$nlog^2$ 线段树合并顺便维护一下$nlogn$ 注意是叶子为n 总结点2n 代码: #include <bits/stdc++.h> usin ...

随机推荐

  1. 2018 ACM 网络选拔赛 青岛赛区

    一些题目的代码被网站吞了…… Problem B. Red Black Tree http://acm.zju.edu.cn/onlinejudge/searchProblem.do?contestI ...

  2. 斯坦福大学公开课机器学习: advice for applying machine learning | regularization and bais/variance(机器学习中方差和偏差如何相互影响、以及和算法的正则化之间的相互关系)

    算法正则化可以有效地防止过拟合, 但正则化跟算法的偏差和方差又有什么关系呢?下面主要讨论一下方差和偏差两者之间是如何相互影响的.以及和算法的正则化之间的相互关系 假如我们要对高阶的多项式进行拟合,为了 ...

  3. C++基础知识--DAY2

    昨天我们主要是讲的C++相对于C语言的变化,结尾讲述了一点引用的基础知识,要明白,引用就是对一个变量取别名,在C++中需要用指针的都可以思考是否可以用引用来代替. 1. 常引用 常引用(const s ...

  4. jquery 获取$("#id").text()里面的值 需要进行去空格去换行符操作

    Jquery:$("#accuracy").val($("#accuracy").val().replace(/\ +/g,""));//去 ...

  5. hystrix实战之javanica

    spingboot2.0.3集成hystrix的,访问dashboard的另外一种方式: https://blog.csdn.net/qq_38455201/article/details/80783 ...

  6. 新建体(2):create or replace object创建存储包、存储过程、函数

    http://heisetoufa.iteye.com/blog/366957/ 创建一个package(包) 声明: create or replace package mpay_route is ...

  7. QT: 自定义断言;

    使用Qt  creator + mingw + gdb进行qt项目开发时,应用Q_ASSERT进行断言总是会出现问题:  断言失败,程序崩溃而不是停止: 采用自定义断言能完美解决该问题(方法取自于国外 ...

  8. 使用Redis模拟简单分布式锁,解决单点故障的问题

    需求描述: 最近做一个项目,项目中有一个功能,每天定时(凌晨1点)从数据库中获取需要爬虫的URL,并发送到对应的队列中,然后客户端监听对应的队列,然后执行任务.如果同时部署多个定时任务节点的话,每个节 ...

  9. 20165232 2017-2018-2《Java程序设计》课程总结

    20165232 2017-2018-2<Java程序设计>课程总结 每周作业链接汇总: 我期望的师生关系 学习基础和c语言基础调查 预备作业3 Linux安装及学习 第一周学习总结 第二 ...

  10. Feature Selection

    两方面(发散,相关)~三方法(FWE) F:方皮卡互 W:RFE E:惩罚树 一.简介 我们的数据处理后,喂给算法之前,考虑到特征的实际情况,通常会从两个方面考虑来选择特征: 1)特征是否发散:如果一 ...