【题目链接】 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. 贿赂囚犯 Bribe the prisoners ( 动态规划+剪枝)

    一个监狱里有P个并排着的牢房,从左往右一次编号为1,2,-,P.最初所有牢房里面都住着一个囚犯.现在要释放一些囚犯.如果释放某个牢房里的囚犯,必须要贿赂两边所有的囚犯一个金币,直到监狱的两端或者空牢房 ...

  2. adb端口被占用解决

    解决ADB端口占用问题 方式一5037为adb默认端口,若5037端口被占用,查看占用端口的进程PIDC:\Users\wwx229495>netstat -aon|findstr 5037  ...

  3. 设计模式之Prototype

    设计模式总共有23种模式这仅仅是为了一个目的:解耦+解耦+解耦...(高内聚低耦合满足开闭原则) 介绍: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 为什么要用Prototype ...

  4. linux c 执行新程序

    学习进程时,linu c上说新开的进程一般要执行另外一个程序,同时与父进程执行同一个程序没有意义 如下是如何执行一个新的程序 使用exec函数簇 exec函数簇包含如下函数

  5. 【Python学习笔记】Coursera课程《Using Python to Access Web Data 》 密歇根大学 Charles Severance——Week2 Regular Expressions课堂笔记

    Coursera课程<Using Python to Access Web Data > 密歇根大学 Charles Severance Week2 Regular Expressions ...

  6. sunos kernel src

    https://github.com/eocallaghan/AuroraUX-SunOS https://github.com/zoyanhui/coroutine-libtask https:// ...

  7. 在Perl中采用open进行管道操作

    在Perl中采用open进行管道操作 http://blog.sina.com.cn/s/blog_4840fe2a0100b8na.html perl exec管道和子进程 http://blog. ...

  8. EasyHook远程进程注入并hook api的实现

    EasyHook远程进程注入并hook api的实现 http://blog.csdn.net/v6543210/article/details/44276155

  9. BZOJ 3771 生成函数,FFT

    Description 我们讲一个悲伤的故事. 从前有一个贫穷的樵夫在河边砍柴. 这时候河里出现了一个水神,夺过了他的斧头,说: “这把斧头,是不是你的?” 樵夫一看:“是啊是啊!” 水神把斧头扔在一 ...

  10. pypcap 安装

    1.下载winpcap开发包 https://www.winpcap.org/devel.htm 下载https://github.com/pynetwork/pypcap/releases最新发布的 ...