题意:给定一颗有 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(线段树合并)的更多相关文章

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

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

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

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

  3. BZOJ2212 [Poi2011]Tree Rotations 线段树合并 逆序对

    原文链接http://www.cnblogs.com/zhouzhendong/p/8079786.html 题目传送门 - BZOJ2212 题意概括 给一棵n(1≤n≤200000个叶子的二叉树, ...

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

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

  5. BZOJ2212【POI2011】ROT:Tree Rotation 线段树合并

    题意: 给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求叶子遍历序的逆序对最少. 分析: 求逆序对我们可以想到权值线段树,所以我们对每个点建一颗线段树(为了避免空间爆炸,采 ...

  6. Bzoj P2212 [Poi2011]Tree Rotations | 线段树合并

    题目链接 通过观察与思考,我们可以发现,交换一个结点的两棵子树,只对这两棵子树内的节点的逆序对个数有影响,对这两棵子树以外的节点是没有影响的.嗯,然后呢?(っ•̀ω•́)っ 然后,我们就可以对于每一个 ...

  7. 洛谷P3066 [USACO12DEC]逃跑的Barn (线段树合并)

    题目描述It's milking time at Farmer John's farm, but the cows have all run away! Farmer John needs to ro ...

  8. 洛谷P1600 天天爱跑步(线段树合并)

    小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 nn ...

  9. 洛谷P3224 [HNOI2012]永无乡(线段树合并+并查集)

    题目描述 永无乡包含 nnn 座岛,编号从 111 到 nnn ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 nnn 座岛排名,名次用 111 到 nnn 来表示.某些岛之间由巨大的桥连接, ...

  10. [bzoj2212]Tree Rotations(线段树合并)

    解题关键:线段树合并模板题.线段树合并的题目一般都是权值线段树,因为结构相同,求逆序对时,遍历权值线段树的过程就是遍历所有mid的过程,所有能求出所有逆序对. #include<iostream ...

随机推荐

  1. 三维模型OSGB格式轻量化技术在大规模场景的加载和渲染的作用分析

    三维模型OSGB格式轻量化技术在大规模场景的加载和渲染的作用分析 在移动设备上,大规模场景的加载和渲染是一个不容忽视的问题.对于OSGB格式轻量化处理来说,大规模场景的加载和渲染也是其中一项重要的任务 ...

  2. Robot 框架学习笔记

    Robot 框架学习笔记 为了更好地让读者理解快速学习新框架的思路,笔者接下来会继续介绍另一个名为 Robot 的自动化测试框架,希望读者能参考笔者从零开始讲解一个开发/测试框架的流程,从中总结出适合 ...

  3. 大规模 IoT 边缘容器集群管理的几种架构-6-个人体验及推荐

    前文回顾 大规模 IoT 边缘容器集群管理的几种架构-0-边缘容器及架构简介 大规模 IoT 边缘容器集群管理的几种架构-1-Rancher+K3s 大规模 IoT 边缘容器集群管理的几种架构-2-H ...

  4. 《Linux基础》04. 用户管理 · 用户组 · 相关文件 · 权限管理

    @ 目录 1:用户管理指令 1.1:添加用户 1.2:修改用户密码 1.3:用户切换与注销 1.4:删除用户 1.5:查询用户信息 1.6:查看当前登录用户 1.7:查看有哪些用户 2:用户组指令 2 ...

  5. C++ 算法竞赛、02 周赛篇 | AcWing 第2场周赛

    AcWing 第2场周赛 竞赛 - AcWing 3626 三元一次方程 AcWing 3626. 三元一次方程 - AcWing 两层循环 #include <iostream> usi ...

  6. .NET C#基础(9):资源释放 - 需要介入的资源管理

    1. 什么是IDisposable?   IDisposable接口是一个用于约定可进行释放资源操作的接口,一个类实现该接口则意味着可以使用接口约定的方法Dispose来释放资源.其定义如下: pub ...

  7. Lua5.3 笔记

    Lua5.3 笔记 最近用skynet,sproto通讯,完全看不懂通讯二进制是怎么写的,发现都是string这个,string那个,完全理解不来. 于是查了一下string.pack的api,和之前 ...

  8. 逻辑漏洞挖掘之XSS漏洞原理分析及实战演练

    一.前言 2月份的1.2亿条用户地址信息泄露再次给各大公司敲响了警钟,数据安全的重要性愈加凸显,这也更加坚定了我们推行安全测试常态化的决心.随着测试组安全测试常态化的推进,有更多的同事对逻辑漏洞产生了 ...

  9. 基于 Wiki.js 搭建知识库系统

    前言 本文介绍如何使用 Wiki.js 搭建知识库系统. Wiki.js 官网 安装 前提准备 Wiki.js 几乎可以在任何支持 Node.js 的系统上运行.它可以运行在 Linux .Windo ...

  10. 「note」原根照抄

    阶(multiplicative order) \(\textbf{Def.}\):\(\delta_m(a)\) 为最小的 \(n\) 使得 \(a^n\equiv 1\pmod m\),其中 \( ...