题目传送门

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.

输入输出样例

输入样例#1:

3
0
0
3
1
2
输出样例#1:

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 [线段树合并]的更多相关文章

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

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

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

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

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

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

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

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

  5. 洛谷 P2824 [HEOI2016/TJOI2016]排序 (线段树合并)

    (另外:题解中有一种思路很高妙而且看上去可以适用一些其他情况的离线方法) 线段树合并&复杂度的简单说明:https://blog.csdn.net/zawedx/article/details ...

  6. P3521 [POI2011]ROT-Tree Rotations (线段树合并)

    P3521 [POI2011]ROT-Tree Rotations 题意: 给你一颗树,只有叶子节点有权值,你可以交换一个点的左右子树,问你最小的逆序对数 题解: 线段树维护权值个个数即可 然后左右子 ...

  7. loj2163 / bzoj2212 / P3521 [POI2011]ROT-Tree Rotations(线段树合并)

    P3521 [POI2011]ROT-Tree Rotations loj2163 [POI2011]ROT-Tree Rotations(数据加强) (loj的数据套了个fread优化才过...) ...

  8. 洛谷P4556 雨天的尾巴(线段树合并)

    洛谷P4556 雨天的尾巴 题目链接 题解: 因为一个点可能存放多种物品,直接开二维数组进行统计时间.空间复杂度都不能承受.因为每一个点所拥有的物品只与其子树中的点有关,所以可以考虑对每一个点来建立一 ...

  9. P3521 [POI2011]ROT-Tree Rotations(线段树合并)

    一句话题意(不用我改了.....):给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. ......这题输入很神烦呐... 给你一棵二叉树的dfs序 ...

  10. BZOJ_2212_[Poi2011]Tree Rotations_线段树合并

    BZOJ_2212_[Poi2011]Tree Rotations_线段树合并 Description Byteasar the gardener is growing a rare tree cal ...

随机推荐

  1. stl第二级空间配置器详解(1)

    SGI STL考虑到小型内存区块的碎片问题,设计了双层级配置器,第一级配置直接使用malloc()和free():第二级配置器则视情况采用不同的策略,当配置区大于128bytes时,直接调用第一级配置 ...

  2. Windows系统环境下Solr之Java实战(二)配置从MySQL数据库批量导入索引

    1.将D:\JavaWeb\Solr\solr-6.2.0\dist下面的solr-dataimporthandler-6.2.0.jar和solr-dataimporthandler-extras- ...

  3. [转载]浅析为什么char类型的范围是 —128~+127

    http://blog.csdn.net/daiyutage/article/details/8575248 在C语言中, signed char 类型的范围为-128~127,每本教科书上也这么写, ...

  4. [php]mysql操作流程

    这种是比较老的一种mysql连接方法 1.连接数据库 $this->con = mysql_connect($this->host, $this->user, $this->p ...

  5. Spark MLlib使用有感

    这些天在公司里面做文本分析的任务,我跟着玻哥一起做,先研究了算法的可行度,最后决定使用Google的Word2Vector和LDA算法来对文本进行分析.之前因为看过一些Spark的东西,所以准备瞄准M ...

  6. springboot中报异常Whitelabel Error Page

    开始以为是url写错了,但其实不是,然后启动application类在的包是要在最顶部,并且和pom中groupid一样 这个也没错,后来发现能访问RestController中的url,但是进不了方 ...

  7. 【技巧总结】Penetration Test Engineer[3]-Web-Security(SQL注入、XXS、代码注入、命令执行、变量覆盖、XSS)

    3.Web安全基础 3.1.HTTP协议 1)TCP/IP协议-HTTP 应用层:HTTP.FTP.TELNET.DNS.POP3 传输层:TCP.UDP 网络层:IP.ICMP.ARP 2)常用方法 ...

  8. jenkins 入门教程(上)【转】

    转自:https://www.cnblogs.com/yjmyzz/p/jenkins-tutorial-part-1.html jenkins是一个广泛用于持续构建的可视化web工具,持续构建说得更 ...

  9. bash脚本里su命令执行

    俩种方法 1.可以使用 <<EOF 参数实现. 脚本内容:cat test.sh代码如下: #!/bin/bashsu - test <<EOFpwd;exit;EOF 2.当 ...

  10. .net 运行中出现的错误解决方法记录

    1.应用程序无法启动,因为应用程序的并行配置不正确.有关详细信息,请参阅应用程序事件日志,或使用命令行sxstrace.exe工具. https://jingyan.baidu.com/article ...