洛谷P3521 [POI2011]ROT-Tree Rotation [线段树合并]
Tree Rotation
题目描述
Byteasar the gardener is growing a rare tree called Rotatus Informatikus.
It has some interesting features:
The tree consists of straight branches, bifurcations and leaves.
The trunk stemming from the ground is also a branch.
Each branch ends with either a bifurcation or a leaf on its top end.
Exactly two branches fork out from a bifurcation at the end of a branch - the left branch and the right branch.
Each leaf of the tree is labelled with an integer from the range 1..n1..n.
The labels of leaves are unique.
With some gardening work, a so called rotation can be performed on any bifurcation, swapping the left and right branches that fork out of it.
The corona of the tree is the sequence of integers obtained by reading the leaves' labels from left to right.
Byteasar is from the old town of Byteburg and, like all true Byteburgers, praises neatness and order.
He wonders how neat can his tree become thanks to appropriate rotations.
The neatness of a tree is measured by the number of inversions in its corona, i.e. the number of pairs (i,j)(i,j), 1\le i<j\le n1≤i<j≤n such that a_i>a_jai>aj in the corona a_1,a_2,\cdots,a_na1,a2,⋯,an.
The original tree (on the left) with corona 3,1,23,1,2 has two inversions.
A single rotation gives a tree (on the right) with corona 1,3,21,3,2, which has only one inversion.
Each of these two trees has 5 branches.
Write a program that determines the minimum number of inversions in the corona of Byteasar's tree that can be obtained by rotations.
给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少。
输入输出格式
输入格式:
In the first line of the standard input there is a single integer nn(2\le n\le 200\ 0002≤n≤200 000) that denotes the number of leaves in Byteasar's tree.
Next, the description of the tree follows.
The tree is defined recursively:
if there is a leaf labelled with pp (1\le p\le n1≤p≤n) at the end of the trunk (i.e., the branch from which the tree stems),then the tree's description consists of a single line containing a single integer pp
if there is a bifurcation at the end of the trunk, then the tree's description consists of three parts:
- the first line holds a single number 00
- then the description of the left subtree follows (as if the left branch forking out of the bifurcation was its trunk),
- and finally the description of the right subtree follows (as if the right branch forking out of the bifurcation was its trunk).
In tests worth at least 30% of the points it additionally holds that n\le 5\ 000n≤5 000.
输出格式:
In the first and only line of the standard output a single integer is to be printed:
the minimum number of inversions in the corona of the input tree that can be obtained by a sequence of rotations.
输入输出样例
3
0
0
3
1
2
1
说明
给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少。
分析:
线段树合并的模板题。
线段树合并是一种常用的技巧,一般是对权值线段树合并,方法也很简单,将两棵线段树上的权值相加即可,一般用于权值线段树。
另外关于这题的答案统计,在合并的过程中只要把子节点的线段树放在左边,当前节点的线段树放在右边,然后子节点的左边与当前节点的右边相乘得到的就是不交换子节点得到的答案,子节点的右边与当前节点的左边相乘得到的就是交换子节点得到的答案。(正确性易证)
Code:
//It is made by HolseLee on 15th Oct 2018
//Luogu.org P3521
#include<bits/stdc++.h>
using namespace std; typedef long long ll;
const int N=1e7+;
int n,tot,ls[N],rs[N],seg[N];
ll ans,ret1,ret2; inline int read()
{
char ch=getchar(); int num=; bool flag=false;
while( ch<'' || ch>'' ) {
if( ch=='-' ) flag=false; ch=getchar();
}
while( ch>='' && ch<='' ) {
num=num*+ch-''; ch=getchar();
}
return flag ? -num : num;
} int build(int l,int r,int x)
{
seg[++tot]=;
if( l==r ) return tot;
int mid=(l+r)>>;
int rt=tot;
if( x<=mid ) ls[rt]=build(l,mid,x);
else rs[rt]=build(mid+,r,x);
return rt;
} int merge(int l,int r,int x,int y)
{
if( !x || !y ) return x+y;
if( l==r ) {
seg[++tot]=seg[x]+seg[y];
return tot;
}
int rt=++tot, mid=(l+r)>>;
ret1+=(ll)seg[ls[x]]*seg[rs[y]];
ret2+=(ll)seg[rs[x]]*seg[ls[y]];
ls[rt]=merge(l,mid,ls[x],ls[y]);
rs[rt]=merge(mid+,r,rs[x],rs[y]);
seg[rt]=seg[ls[rt]]+seg[rs[rt]];
return rt;
} int get()
{
int tmp=read();
if( tmp ) return build(,n,tmp);
int now=merge(,n,get(),get());
ans+=min(ret1,ret2);
ret1=ret2=;
return now;
} int main()
{
n=read();
get(); printf("%lld\n",ans);
return ;
}
洛谷P3521 [POI2011]ROT-Tree Rotation [线段树合并]的更多相关文章
- BZOJ2212【POI2011】ROT:Tree Rotation 线段树合并
题意: 给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求叶子遍历序的逆序对最少. 分析: 求逆序对我们可以想到权值线段树,所以我们对每个点建一颗线段树(为了避免空间爆炸,采 ...
- 洛谷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 来表示.某些岛之间由巨大的桥连接, ...
- 洛谷 P2824 [HEOI2016/TJOI2016]排序 (线段树合并)
(另外:题解中有一种思路很高妙而且看上去可以适用一些其他情况的离线方法) 线段树合并&复杂度的简单说明:https://blog.csdn.net/zawedx/article/details ...
- P3521 [POI2011]ROT-Tree Rotations (线段树合并)
P3521 [POI2011]ROT-Tree Rotations 题意: 给你一颗树,只有叶子节点有权值,你可以交换一个点的左右子树,问你最小的逆序对数 题解: 线段树维护权值个个数即可 然后左右子 ...
- loj2163 / bzoj2212 / P3521 [POI2011]ROT-Tree Rotations(线段树合并)
P3521 [POI2011]ROT-Tree Rotations loj2163 [POI2011]ROT-Tree Rotations(数据加强) (loj的数据套了个fread优化才过...) ...
- 洛谷P4556 雨天的尾巴(线段树合并)
洛谷P4556 雨天的尾巴 题目链接 题解: 因为一个点可能存放多种物品,直接开二维数组进行统计时间.空间复杂度都不能承受.因为每一个点所拥有的物品只与其子树中的点有关,所以可以考虑对每一个点来建立一 ...
- P3521 [POI2011]ROT-Tree Rotations(线段树合并)
一句话题意(不用我改了.....):给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. ......这题输入很神烦呐... 给你一棵二叉树的dfs序 ...
- BZOJ_2212_[Poi2011]Tree Rotations_线段树合并
BZOJ_2212_[Poi2011]Tree Rotations_线段树合并 Description Byteasar the gardener is growing a rare tree cal ...
随机推荐
- asp启用父路径
开启父路径后可以用../来表示上一层目录,如果网站程序中使用了../,不开启则网站程序里有../就会报错. IIS6启用父路径方法:打开IIS管理器——网站——右键属性——主目录——配置——选项——选 ...
- HDU 2058 The sum problem 数学题
解题报告:可以说是一个纯数学题,要用到二元一次和二元二次解方程,我们假设[a,b]这个区间的所有的数的和是N,由此,我们可以得到以下公式: (b-a+1)*(a+b) / 2 = N;很显然,这是一个 ...
- C# 安装部署Windows服务脚本
@echo off Installutil.exe 程序目录 F:\test\TestWindows.exe 服务程序目录 @sc start "服务名称" @sc config ...
- JS设计模式——12.装饰者模式
装饰者模式概述 本章讨论的是一种为对象添加特性的技术,她并不使用创建新子类这种手段. 装饰者模式可以用来透明的把对象包装在具有同样接口的另一个对象中.这样一来,就可以给一个方法添加一些行为,然后将方法 ...
- mysql条件查询中AND与OR联合使用的注意事项!
mysql查询中经常会用到AND与OR一起使用的情况,可如果写法不对,往往会起到相反的效果,这不,前几天就碰到了,最后测试果然提了一堆bug!!!! 废话就不多说了,主要总结一下几点: 一 当mysq ...
- 39 - 同步-异步-IO多路复用
目录 1 同步与异步 2 阻塞与非阻塞 3 什么是IO 3.1 内核态用户态 3.2 IO两个阶段 3.3 IO模型 3.3.1 同步阻塞IO 3.3.2 同步非阻塞IO 3.3.3 IO多路复用 3 ...
- Nginx/LVS/HAProxy负载均衡软件的优缺点详解【转】
转自 (总结)Nginx/LVS/HAProxy负载均衡软件的优缺点详解http://www.ha97.com/5646.html PS:Nginx/LVS/HAProxy是目前使用最广泛的三种负载均 ...
- jQuery学习(二) 自定义扩展函数
jQuery函数调用写法很优雅,在项目开发过程中,有需要自定义函数经常被使用到,将这些函数放置到项目ExtTool.js中,为了编码方式的统一,也希望这些自定义函数与jQuery函数一致的调用方式.在 ...
- ETL利器Kettle实战应用解析系列二
本系列文章主要索引如下: 一.ETL利器Kettle实战应用解析系列一[Kettle使用介绍] 二.ETL利器Kettle实战应用解析系列二 [应用场景和实战DEMO下载] 三.ETL利器Kettle ...
- 项目中遇到的问题:Gradle传递性依赖冲突
问题描述: 在调用别人接口时,由于他们接口做了拦截处理在使用RestTemplate调用时必须要使用@Qualifier("他们封装好的类"),需要导入jar包 gradle方式导 ...