【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=2212

【题目大意】

  给出一棵二叉树,每个叶节点上有一个权值,现在可以任意交换左右儿子,
  使得逆序对最少,求最少的逆序对数量

【题解】

  我们发现对于每个非叶节点来说,其贡献值为左右两个儿子的权值树上,
  每个节点想反位置的数量和乘积,比如左儿子的权值树左节点和右儿子权值树的右节点相乘,
  那么我们对于每个节点建立一颗权值线段树,仅保留非0链,
  递归合并这些权值线段树,同时每次将相反位置数量乘积的最小值累加到答案即可

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N=400010,M=N*20;
typedef long long LL;
int n,a[N],cnt,Root,root[N];
int Tree[N][2];
LL Ans,Ans0,Ans1;
void Read_Tree(int &x){
x=++cnt;
scanf("%d",&a[x]);
if(a[x])return;
Read_Tree(Tree[x][0]);
Read_Tree(Tree[x][1]);
}
namespace Segment_Tree{
int tot;
struct node{int l,r,a,b,sum;}T[M];
void up(int x){T[x].sum=T[T[x].l].sum+T[T[x].r].sum;}
int build(int l,int r,int p){
int x=++tot;
T[x].a=l; T[x].b=r; T[x].sum=0;
if(l==r){T[x].sum=1;return x;}
int mid=(l+r)>>1;
if(p<=mid){T[x].l=build(l,mid,p);}
else{T[x].r=build(mid+1,r,p);}
return up(x),x;
}
int merge(int x,int y){
if(!x||!y)return x^y;
Ans0+=(LL)T[T[x].r].sum*(LL)T[T[y].l].sum;
Ans1+=(LL)T[T[x].l].sum*(LL)T[T[y].r].sum;
T[x].l=merge(T[x].l,T[y].l);
T[x].r=merge(T[x].r,T[y].r);
return up(x),x;
}
void dfs(int x){
if(a[x])return;
dfs(Tree[x][0]); dfs(Tree[x][1]);
Ans0=Ans1=0;
root[x]=merge(root[Tree[x][0]],root[Tree[x][1]]);
Ans+=min(Ans0,Ans1);
}
}
int main(){
scanf("%d",&n);
Read_Tree(Root);
for(int i=1;i<=cnt;i++)if(a[i]!=0)root[i]=Segment_Tree::build(1,n,a[i]);
Segment_Tree::dfs(Root);
printf("%lld\n",Ans);
return 0;
}

BZOJ 2212 [Poi2011]Tree Rotations(线段树合并)的更多相关文章

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

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

  2. BZOJ 2212: [Poi2011]Tree Rotations( 线段树 )

    线段树的合并..对于一个点x, 我们只需考虑是否需要交换左右儿子, 递归处理左右儿子. #include<bits/stdc++.h> using namespace std; #defi ...

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

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

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

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

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

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

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

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

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

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

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

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

  9. bzoj 2212 : [Poi2011]Tree Rotations (线段树合并)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2212 思路:用线段树合并求出交换左右儿子之前之后逆序对的数量,如果数量变小则交换. 实现 ...

  10. [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】

    题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...

随机推荐

  1. 2017-3-26 webpack入门(一)

    2017-3-26 webpack入门(一) webpack 前端 打包 最近项目里用到了webpack特意总结一下.来源:http://webpackdoc.com 1 概念 1.1 webpack ...

  2. jeecg3.7中弹出窗操作标签dgOpenOpt的用法

    1.基本参数 参数名                    描述 url                           弹出页面地址 title                         ...

  3. 通过实例来学习XML DTD

    使用DTD的原因: 注意:由于它自身的一些缺点,DTD终将被淘汰,但是它还是要学习的.学习完DTD后,后面继续学习XML Schema. 1,通过 DTD,您的每一个 XML 文件均可携带一个有关其自 ...

  4. visual studio 个性化设置

    尼马visual studio 的注释建设的真垃圾 Ctrl+K+C Ctrl+K+U, 通过工具->选项->环境->键盘->命令包含中搜索“注释选定内容”,分配成 Ctrl+ ...

  5. 解决TextView多行滑动与NestedScrollView等,滑动冲突,我的解决方案

    1.首先要明白,什么时候回TextView处理滑动,什么时候不处理滑动 1.1往上滑动,到达文本底部就不要再处理了,如果往上滑动不在底部则继续TextView滑动 1.2往下滑动,到达文本顶部就不要再 ...

  6. 类似于input输入框placeholder的效果,兼容ie8

    $(function(){    //判断浏览器是否支持placeholder属性  supportPlaceholder='placeholder'in document.createElement ...

  7. 刷题中熟悉Shell命令之Tenth Line和Transpose File [leetcode]

    首先介绍题目中要用的4个Shell命令 sed awk head tail的常用方法.(打好地基,才能建成高楼!) sed:(转自:http://www.cnblogs.com/barrychiao/ ...

  8. ajax登录请求,无法跳转

    没有用form提交数据,用的ajax提交.服务器显示已经登录成功,并且返回了成功代码OK.却无法进行跳转: js代码: $("input[type='submit']").on(& ...

  9. 用eclipse运行项目时怎么设置虚拟机内存大小

    方法一: 打开eclipse,选择Window--Preferences...在对话框左边的树上双击Java,再双击InstalledJREs,在右边选择前面有对勾的JRE,再单击右边的“Edit”按 ...

  10. Django 批量导入文件

    1. 按照xlrd软件 pip3 install xlrd 2. POST提交文件获取数据 方法一:写入硬盘,xlrd读取xlsx文件获取文件数据 def batch_view(self,reques ...