题意:

  给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求叶子遍历序的逆序对最少。

分析:

  求逆序对我们可以想到权值线段树,所以我们对每个点建一颗线段树(为了避免空间爆炸,采取动态开点的科技)

  两个子节点可以交换,于是我们可以递归,自底向上贪心解决问题,每次线段树合并,在合并时,统计交换左右子节点后,横跨当前位置的逆序对数量,以及不交换子节点的情况下的这个数量,将更优的计入答案。这道问题就圆满解决了。

代码:

 #include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=;
struct node{ll v;int ls,rs;}t[N*];
int n,m,tot=,cnt=,nm[N],ls[N],rs[N],rt[N];
ll ans=,ans1,ans2;
void read(int x){
scanf("%d",&nm[x]);
if(!nm[x]) read(ls[x]=++cnt),
read(rs[x]=++cnt);return ;
} void update(int &x,int l,int r,int v){
if(!x) x=++tot;int mid=l+r>>;
if(l==r){t[x].v=;return ;}
if(v<=mid) update(t[x].ls,l,mid,v);
else update(t[x].rs,mid+,r,v);
t[x].v=t[t[x].rs].v+t[t[x].ls].v;
} int merge(int x,int y){
if(!x||!y) return x|y;
ans1+=(ll)t[t[x].rs].v*t[t[y].ls].v;
ans2+=(ll)t[t[x].ls].v*t[t[y].rs].v;
t[x].ls=merge(t[x].ls,t[y].ls);
t[x].rs=merge(t[x].rs,t[y].rs);
t[x].v=t[t[x].ls].v+t[t[x].rs].v;
return x;
} void dfs(int x){
if(!x) return ;
dfs(ls[x]);dfs(rs[x]);
if(!nm[x]){
ans1=ans2=;
rt[x]=merge(rt[ls[x]],rt[rs[x]]);
ans+=min(ans1,ans2);
} return ;
} int main(){
scanf("%d",&n);read();
for(int i=;i<=cnt;i++)
if(nm[i]) update(rt[i],,n,nm[i]);
dfs();printf("%lld\n",ans);
return ;
}

线段树合并

BZOJ2212【POI2011】ROT:Tree Rotation 线段树合并的更多相关文章

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

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

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

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

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

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

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

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

  5. 洛谷P3521 [POI2011]ROT-Tree Rotation [线段树合并]

    题目传送门 Tree Rotation 题目描述 Byteasar the gardener is growing a rare tree called Rotatus Informatikus. I ...

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

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

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

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

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

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

  9. bzoj2212/3702 [Poi2011]Tree Rotations 线段树合并

    Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some in ...

随机推荐

  1. JSON与JSONP(转载)

    JSON是一种数据交换格式,JSONP是非官方跨域数据交互协议.一个是描述信息的格式,一个是信息传递双方约定的方法.       一.JSON是一种基于文本的数据交换方式,或者叫做数据描述格式.   ...

  2. 清除当前文件夹下.svn文件的方法

    把如下命令拷贝到一个文件中,并保存为bat后缀的文件:然后把这个bat文件保存到相应文件夹下. @echo on color 2f mode con: cols=80 lines=25 @REM @e ...

  3. IDE工具的[多行光标编辑模式]

    Sublime Text3:Ctrl+Alt+上下键 Eclipse:Shift+Alt+A,进入退出多光标模式 IDEA:Shift + ctrl + alt + 鼠标左键 收集链接 IDEA:ht ...

  4. bzoj 3830: [Poi2014]Freight【dp】

    参考:https://blog.csdn.net/zqh_wz/article/details/52953516 妙啊 看成分段问题,因为火车只能一批一批的走(易证= =)设f[i]为到i为止的车都走 ...

  5. 安装 Spring 框架库

    下载地址:http://repo.spring.io/release/org/springframework/spring

  6. python的Template使用指南

    本文主要讲解了python中Template使用方法以及使用技巧,非常实用,有需要的朋友可以参考下: Template无疑是一个好东西,可以将字符串的格式固定下来,重复利用.同时Template也可以 ...

  7. 题解报告:hdu 1075 What Are You Talking About

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1075 Problem Description Ignatius is so lucky that he ...

  8. LinkedList,SortedList 基本用法

    LinkedList类是双向列表,列表中的每个节点都包含了对前一个和后一个元素的引用. LinkedList<int> ma = new LinkedList<int>(); ...

  9. github下载下来的C#控制台小游戏[含源码]

    早就听说了github是世界最大的源码库,但自己却不是很懂,今天去研究了下,注册了一个帐号,然后在上面搜索了一下C# game,然后发现有许多的游戏. 随意地选择了一个,感觉比较简单,于是就下载了下来 ...

  10. js中判断数据类型的方法 typeof

    <input type="text" onblur="demo(this)"/><br/> <input type="n ...