【题目链接】 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. 牛客网刷题(纯java题型 31~60题)

    牛客网刷题(纯java题型 31~60题) 重写Override应该满足"三同一大一小"三同:方法名相同,参数列表相同,返回值相同或者子类的返回值是父类的子类(这一点是经过验证的) ...

  2. bzoj 1197 DP

    我们可以将这个问题转化为在n维空间中一共放m个n维球,求这m个球最多将这个空间分为不同的几个部分. 那么我们设w[i][j]代表i为空间放j个球分为的部分,那么w[i][j]=w[i][j-1]+w[ ...

  3. 网络设备之net_device结构与操作

    net_device结构是一个很大的结构,其中包含了硬件信息,接口信息,其他辅助信息,以及设备操作函数等: 目前仍在读代码中,后续字段注释会逐渐补充: /** * struct net_device ...

  4. linux驱动基础系列--Linux mmc sd sdio驱动分析

    前言 主要是想对Linux mmc子系统(包含mmc sd sdio)驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.块设备驱动.设备模型等也不进行详细说明原 ...

  5. sicily 数据结构 1014. Translation

    Description You have just moved from Waterloo to a big city. The people here speak an incomprehensib ...

  6. OC 07 类的扩展

    1.NSDate的使用 NSDate是Cocoa中⽤于处理⽇期和时间的基础类,封装了某⼀给定的时刻(含日期,时间,时区) 注意NSLog(@“%@”,nowDate);⽆论你是哪个时区的时间,打印时总 ...

  7. php设计模式五----适配器模式

    1.简介 适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁.这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能. 意图:将一个类的接口转换成客户希望的另外一个接口 ...

  8. 【python】if __name__ == '__main__'

    转载自:http://www.cnblogs.com/xuxm2007/archive/2010/08/04/1792463.html 当你打开一个.py文件时,经常会在代码的最下面看到if __na ...

  9. phpcms v9表单向导添加验证码

    要做留言板的功能,故用添加表单,想要在提交留言前加一个验证码的功能.网上的教程比较混乱,于是亲自实验了下,步骤如下: 首先是调用表单的页面加入验证码.表单js调用模版默认的是 \phpcms\temp ...

  10. 机器学习方法(四):决策树Decision Tree原理与实现技巧

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术.应用感兴趣的同学加入. 前面三篇写了线性回归,lass ...