题意

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

分析

可以发现如果交换非叶结点的左右子树,对子树内的交换无影响,对子树外的交换也无影响,所以答案的贡献只是左子树与右子树之间是否交换得到的最小的逆序对数。

题解

考虑分治,对于一个点\(x\),我们只需要将其其中的一个子树的叶子插入到bit中,然后用另一个子树的叶子就能求得其逆序对数。那么发现一个点在遍历过程中可能插入的次数不只1次,对复杂度的影响主要就是重复插入的那些点(否则复杂度是\(O(nlogn)\)的)。由于无论是将哪棵子树插入到bit中都能求得其答案,所以我们贪心的将叶子数最小的那棵子树插入到bit中即可。这样插入到\(bit\)的次数总共不超过\(n\)次。所以复杂度是\(O(nlogn)\)的。

#include <bits/stdc++.h>
using namespace std;
inline int getint() {
int x=0, c=getchar();
for(; c<48||c>57; c=getchar());
for(; c>47&&c<58; x=x*10+c-48, c=getchar());
return x;
}
const int N=200005, M=N*3;
typedef long long ll;
int a[N], b[M][2], c[M][2], d[N], now, tot, s[M], n;
ll ans;
void upd(int x, int g) {
for(; x<=n; x+=x&-x) {
d[x]+=g;
}
}
int sum(int x) {
int y=0;
for(; x; x-=x&-x) {
y+=d[x];
}
return y;
}
void dfs1(int x) {
int w=getint();
if(w) {
a[++tot]=w;
c[x][0]=-w;
b[x][0]=tot;
b[x][1]=tot;
s[x]=1;
return;
}
int l, r;
dfs1(c[x][0]=l=++now);
dfs1(c[x][1]=r=++now);
b[x][0]=b[l][0];
b[x][1]=b[r][1];
s[x]=s[l]+s[r];
}
void dfs2(int x) {
if(s[x]==1) {
upd(-c[x][0], 1);
return;
}
int ch=s[c[x][1]]<s[c[x][0]], l=c[x][ch], r=c[x][ch^1];
dfs2(l);
for(int i=b[l][0], g=b[l][1]; i<=g; upd(a[i++], -1));
dfs2(r);
ll mn=0, mx=0;
for(int i=b[l][0], g=b[l][1]; i<=g; ++i) {
int t=sum(a[i]-1);
mn+=t;
mx+=s[r]-t;
}
ans+=min(mn, mx);
for(int i=b[l][0], g=b[l][1]; i<=g; upd(a[i++], 1));
}
int main() {
n=getint();
dfs1(now=1);
dfs2(1);
printf("%lld\n", ans);
return 0;
}

【BZOJ】2212: [Poi2011]Tree Rotations的更多相关文章

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

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

  2. 2212: [Poi2011]Tree Rotations

    2212: [Poi2011]Tree Rotations https://www.lydsy.com/JudgeOnline/problem.php?id=2212 分析: 线段树合并. 首先对每个 ...

  3. BZOJ 2212 [Poi2011]Tree Rotations(线段树合并)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2212 [题目大意] 给出一棵二叉树,每个叶节点上有一个权值,现在可以任意交换左右儿子, ...

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

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

  5. bzoj 2212: [Poi2011]Tree Rotations

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

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

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

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

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

  8. 【BZOJ】2277: [Poi2011]Strongbox

    题意 有一个密码箱,\(0\)到\(n-1\)中的某些整数是它的密码.如果\(a\)和\(b\)都是它的密码,那么\((a+b)%n\)也是它的密码(\(a,b\)可以相等).某人试了\(k\)次密码 ...

  9. 【BZOJ】2216: [Poi2011]Lightning Conductor

    题意 给一个长度为\(n\)的序列\(a_i\),对于每个\(1 \le i \le n\),找到最小的非负整数\(p\)满足 对于任意的\(j\), \(a_j \le a_i + p - \sqr ...

随机推荐

  1. 《Linux私房菜》笔记和问题记录

    鸟哥的Linux私房菜简体首页 对Linux的学习侧重于基本命令和运维相关的部分,最后章节的测试问题不错. 1.VIM程序编辑器 1.所有的Linux都会内建VI:很多软件的编辑接口都会主动呼叫VI: ...

  2. 算法系列:HMM

    隐马尔可夫(HMM)好讲,简单易懂不好讲. 用最经典的例子,掷骰子.假设我手里有三个不同的骰子.第一个骰子是我们平常见的骰子(称这个骰子为D6),6个面,每个面(1,2,3,4,5,6)出现的概率是1 ...

  3. 运维自动化之ansible的安装与使用(包括模块与playbook使用)(转发)

    原文  http://dl528888.blog.51cto.com/2382721/1435415 我使用过puppet(地址是http://dl528888.blog.51cto.com/2382 ...

  4. 如何安装sublime text2以及它的插件?

    下载Sublime Text2的安装包,安装,安装后打开的界面如图   下面我们来给他安装插件,首先安装packagecontrol,打开菜单栏中的View-->show console   在 ...

  5. WPF PRISM开发入门一( 初始化PRISM WPF程序)

    这篇博客将介绍在WPF项目中引入PRISM框架进行开发的一些基础知识.目前最新的PRISM的版本是Prism 6.1.0,可以在Github上获取PRISM的源码.这个系列的博客将选择PRISM 4. ...

  6. (五)WebRTC手记Channel概念

    转自:http://www.cnblogs.com/fangkm/p/4401075.html 前面两篇博文完整地介绍了WebRTC音视频的采集模块,接下来应该开始介绍关键的音视频编码模块.不过在介绍 ...

  7. 外键为','(逗号)拼接ID,连接查询外键表ID

    select distinct pipeId=substring(a.PipeIn,b.number,charindex(',',a.PipeIn+',',b.number)-b.number) fr ...

  8. 在Visualforce page中用自带的控件实现Ajax回调后台方法(并且可以用js去动态给parameters赋值)

    这里用的组合是:apex:commandLink  + apex:actionFunction + apex:outputPanel 这里的 apex:commandLink 和 apex:actio ...

  9. hdu 5446 Unknown Treasure Lucas定理+中国剩余定理

    Unknown Treasure Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  10. AOP动态代理解析5-cglib代理的实现

    CGLIB是一个强大的高性能的代码生成包.它广泛地被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的Interception(拦截).EasyMock和jMock是通过使 ...