B - Tree Rotations HYSBZ - 2212 (线段树合并)
题目链接: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 (线段树合并)的更多相关文章
- 【bzoj2212】[Poi2011]Tree Rotations 权值线段树合并
原文地址:http://www.cnblogs.com/GXZlegend/p/6826614.html 题目描述 Byteasar the gardener is growing a rare tr ...
- 【bzoj1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+权值线段树合并
题目描述 求一张图的严格次小生成树的边权和,保证存在. 输入 第一行包含两个整数N 和M,表示无向图的点数与边数. 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z ...
- [学习笔记]dsu on a tree(如何远离线段树合并)
https://www.zybuluo.com/ysner/note/1318613 背景 这玩意来源于一种有局限性的算法. 有一种广为人知的,树上离线维护子树信息的做法. (可以参照luogu360 ...
- [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】
题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...
- bzoj 2212 : [Poi2011]Tree Rotations (线段树合并)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2212 思路:用线段树合并求出交换左右儿子之前之后逆序对的数量,如果数量变小则交换. 实现 ...
- BZOJ.2212.[POI2011]Tree Rotations(线段树合并)
题目链接 \(Description\) 给定一棵n个叶子的二叉树,每个叶节点有权值(1<=ai<=n).可以任意的交换两棵子树.问最后顺序遍历树得到的叶子权值序列中,最少的逆序对数是多少 ...
- 【BZOJ2212】[Poi2011]Tree Rotations 线段树合并
[BZOJ2212][Poi2011]Tree Rotations Description Byteasar the gardener is growing a rare tree called Ro ...
- bzoj2212[Poi2011]Tree Rotations [线段树合并]
题面 bzoj ans = 两子树ans + min(左子在前逆序对数, 右子在前逆序对数) 线段树合并 #include <cstdio> #include <cstdlib> ...
- 【BZOJ2212】[POI2011]Tree Rotations (线段树合并)
题解: 傻逼题 启发式合并线段树里面查$nlog^2$ 线段树合并顺便维护一下$nlogn$ 注意是叶子为n 总结点2n 代码: #include <bits/stdc++.h> usin ...
随机推荐
- IO处理要注意的事:关闭资源!关闭资源!关闭资源!
案例1: 现象: 同事做本地txt数据切分然后处理,发现删除本地临时文件目录中的文件时,有时成功,有时删除完了发现文件还在.代码各处都不报错,且各种日志打印正常. 解决: 最后发现,是业务逻辑代码中有 ...
- error:crosses initialization of ...
switch(c) { case 0x01: int temp = a + b; .... break; case 0x02: break; default:break; } 此时会报如题所示错误 原 ...
- 字符输入流 FileReader
package cn.lideng.demo3; import java.io.FileNotFoundException; import java.io.FileReader; public cla ...
- es6基础知识总结(附加)
附加: 字符串扩展: 1. includes(str) : 判断是否包含指定的字符串2. startsWith(str) : 判断是否以指定字符串开头3. endsWith(str) : 判断是否以指 ...
- RHCE基础环境系统的搭建
RHCE基础环境系统的搭建 安装前提: 安装的时候对系统和硬件的要求: 红帽系统安装队系统的要求:Windows操作系统选择64位的内存至少6GCPU需要支持虚拟化技术在做红帽系统实验的时候,把360 ...
- Intellij Idea识别Java Web项目
使用maven生成一个Java项目,手动添加相应的web目录WEB_INF,web.xml等,此时idea没有自动识别为web项目,此时编辑web.xml文件会出现一些不该出现的错误,需要做的就是让i ...
- Hbase balancer RSgroup shell 脚本
#!/bin/bashTMP_FILE=tmp_groupsGROUPS_FILE=groups.txtecho "list_groups" | hbase shell > ...
- python3 bytes数据类型探讨
python3中str和bytes分开了,那么bytes与str之间到底是什么关系呢?下面从表现形式.处理方式.存储形式三个方面来阐述其区别 1. 在字符串前面加上b,就表示bytes数据类型 s1 ...
- termux 开启 sshd
众所周知, termux 上的 sshd 不能通过 IP 连接, 只能使用密钥, 对于使用 PuTTY 的 Windows 用户, 怎么办呢? 由于 PuTTY 支持 telnet, 而 termux ...
- 微信小程序开发(5) 2048游戏
在这篇微信小程序开发教程中,我们将介绍如何使用微信小程序开发2048小游戏. 本文主要分为两个部分,小程序主体部分及小游戏页面部分 一.小程序主体部分 一个小程序主体部分由三个文件组成,必须放在项目的 ...