洛谷3521 [POI2011]ROT-Tree Rotations(线段树合并)
题意:给定一颗有 n 个叶节点的二叉树。每个叶节点都有一个权值pi(注意,根不是叶节点),所有叶节点的权值构成了一个1∼n 的排列。对于这棵二叉树的任何一个结点,保证其要么是叶节点,要么左右两个孩子都存在。现在你可以任选一些节点,交换这些节点的左右子树。在最终的树上,按照先序遍历遍历整棵树并依次写下遇到的叶结点的权值构成一个长度为 n的排列,你需要最小化这个排列的逆序对数。
输入格式:第一行是一个整数 n,表示树的叶节点个数。接下来若干行,使用递归的形式来读入这棵树,读入任意一个子树的信息时,初始时读入其根节点。对于一个结点 u,首先有一行一个整数 x。若 x≠0,则表示 u 是一个叶节点,其权值为 x。若 x = 0,则表示 u 不是叶节点,则接下来若干行读入其左子树信息,左子树读入结束后接下来若干行读入其右子树信息。
输出格式:输出一行一个整数表示最小的逆序对数。
分析:假设当前点的左右儿子分别为ls,rs,很容易发现,交换以这两个结点为根节点的子树,并不会影响他们的祖宗交换时逆序对的个数。所以我们可以考虑每一层贪心地进行交换,此时局部最优即全局最优。同时,对于区间[L,R],设其中点为mid,我们只需要考虑这样的逆序对(x,y),满足L ≤ x ≤ mid,mid+1 ≤ y ≤ R即可,并不需要考虑在同一个子树中的逆序对数量。由于这是权值线段树,那么逆序对其实很好统计,对于两颗线段树代表同一段区间的两个节点,考虑交换与不交换两种情况,分别取左、右部分或者右、左部分统计逆序对个数。最后取最小值就可以了。
#include<cstdio>
const int maxn = 2e5+5; typedef long long ll; int n, x, cnt;
int sum[maxn << 5], ls[maxn << 5], rs[maxn << 5];
ll ans, s1, s2;
int rt[maxn]; inline ll min(ll a, ll b) { return a < b ? a : b; } void ins(int &u, int l, int r, int pos){
if(!u) u = ++cnt; ++sum[u];
if(l == r) { return ; }
int mid = (l + r) >> 1;
if(pos <= mid) ins(ls[u], l, mid, pos);
else ins(rs[u], mid + 1, r, pos);
} void merge(int &a, int b){
if(!a || !b) { a = a | b; return ;}
sum[a] += sum[b];
s1 += 1LL * sum[ls[a]] * sum[rs[b]];
s2 += 1LL * sum[rs[a]] * sum[ls[b]];
merge(ls[a], ls[b]);
merge(rs[a], rs[b]);
sum[a] = sum[ls[a]] + sum[rs[a]];
} int dfs(){
scanf("%d", &x);
if(x) return ins(rt[x], 1, n, x), rt[x];
else{
int ls, rs;
ls = dfs(), rs = dfs();
s1 = s2 = 0;
merge(ls, rs);
ans += min(s1, s2);
return ls;
}
} int main(){
scanf("%d", &n);
dfs();
printf("%lld", ans);
return 0;
}
洛谷3521 [POI2011]ROT-Tree Rotations(线段树合并)的更多相关文章
- 【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 线段树合并 逆序对
原文链接http://www.cnblogs.com/zhouzhendong/p/8079786.html 题目传送门 - BZOJ2212 题意概括 给一棵n(1≤n≤200000个叶子的二叉树, ...
- BZOJ.2212.[POI2011]Tree Rotations(线段树合并)
题目链接 \(Description\) 给定一棵n个叶子的二叉树,每个叶节点有权值(1<=ai<=n).可以任意的交换两棵子树.问最后顺序遍历树得到的叶子权值序列中,最少的逆序对数是多少 ...
- BZOJ2212【POI2011】ROT:Tree Rotation 线段树合并
题意: 给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求叶子遍历序的逆序对最少. 分析: 求逆序对我们可以想到权值线段树,所以我们对每个点建一颗线段树(为了避免空间爆炸,采 ...
- Bzoj P2212 [Poi2011]Tree Rotations | 线段树合并
题目链接 通过观察与思考,我们可以发现,交换一个结点的两棵子树,只对这两棵子树内的节点的逆序对个数有影响,对这两棵子树以外的节点是没有影响的.嗯,然后呢?(っ•̀ω•́)っ 然后,我们就可以对于每一个 ...
- 洛谷P3066 [USACO12DEC]逃跑的Barn (线段树合并)
题目描述It's milking time at Farmer John's farm, but the cows have all run away! Farmer John needs to ro ...
- 洛谷P1600 天天爱跑步(线段树合并)
小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 nn ...
- 洛谷P3224 [HNOI2012]永无乡(线段树合并+并查集)
题目描述 永无乡包含 nnn 座岛,编号从 111 到 nnn ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 nnn 座岛排名,名次用 111 到 nnn 来表示.某些岛之间由巨大的桥连接, ...
- [bzoj2212]Tree Rotations(线段树合并)
解题关键:线段树合并模板题.线段树合并的题目一般都是权值线段树,因为结构相同,求逆序对时,遍历权值线段树的过程就是遍历所有mid的过程,所有能求出所有逆序对. #include<iostream ...
随机推荐
- VMware虚拟机的安装与配置
一.VMware简介 VMware Workstation Pro 是业界标准的桌面 Hypervisor,用于在 Linux 或 Windows PC 上运行虚拟机. Workstation 16 ...
- nflsoj 5924 选排列
与全排列略微有些不同,只需要将退出条件需要改成 u==r #include <iostream> using namespace std; const int N = 15; int r, ...
- 服务端不回应客户端的syn握手,连接建立失败原因排查
背景 测试环境有一个后台服务,部署在内网服务器A上(无外网地址),给app提供接口.app访问这个后台服务时,ip地址是公网地址,那这个请求是如何到达我们的内网服务器A呢,这块我咨询了网络同事,我画了 ...
- mall :sa-token项目源码解析
目录 一.mall开源项目 1.1 来源 1.2 项目转移 1.3 项目克隆 二.Sa-Toekn框架 2.1 Sa-Token 简介 2.2 分布式后端项目的使用流程 2.3 分布式后端项目的使用场 ...
- 在 Visual Studio 2022 中使用文件对比
在最新版本的 Visual Studio 2022 中,加入了新的功能特性--"文件对比". 在开发过程中,开发人员有时会需要比对文件差异,特别是代码文件,之前很多时候是借助版本控 ...
- 《Web安全基础》03. SQL 注入
@ 目录 1:简要 SQL 注入 2:MySQL 注入 2.1:信息获取 2.2:跨库攻击 2.3:文件读写 2.4:常见防护 3:注入方法 3.1:类型方法明确 3.2:盲注 3.3:编码 3.4: ...
- MySQL篇:第一章_软件安装和基本操作
本篇安装软件Navicate Premium 16破解版和phpstudy_pro phpstudy_pro安装教程 phpstudy官网:https://www.xp.cn/download.htm ...
- 爬虫系列——Beautifulsoup4
文章目录 一 介绍 二 基本使用 三 遍历文档树 四 搜索文档树 五 修改文档树 六 总结 一 介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能 ...
- java算法之排序算法大全
①排序 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法.排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方 ...
- 什么???CSS也能原子化!
1.什么是原子化 CSS? Atomic CSS is the approach to CSS architecture that favors small, single-purpose class ...