题意

给一棵\(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. C#的lock关键字

    using System; using System.Threading; namespace Test { class Program { //一.Lock定义 //lock 关键字可以用来确保代码 ...

  2. EasyUI - DataGrid 去右边空白滚动条列 分类: JavaScript 2014-09-03 10:46 1090人阅读 评论(2) 收藏

    熟悉 EasyUI - DataGrid 的童鞋应该会注意到这样一个情景: 想去掉这块,找了下资料,发现也有人同样纠结:http://www.cnblogs.com/hantianwei/p/3440 ...

  3. html5 svg

    html5 svg <html > <body> <p>canvas 用js 绘画,是整幅画布,适合游戏 svg可放大,支持dom 操作,js事件 线性渐变.高斯模 ...

  4. 使用ASP.NET MVC、Rabbit WeixinSDK和Azure快速开发部署微信后台

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:公众号后台系统和数据都基本准备妥当了,可以来分享下我是如何开发本微信公众号的后台系统了 ...

  5. leetcode4568

    date: 2015-09-13 16:32:49 Median of Two Sorted Arrays There are two sorted arrays nums1 and nums2 of ...

  6. HDU 3364 Lanterns 高斯消元

    Lanterns Problem Description   Alice has received a beautiful present from Bob. The present contains ...

  7. Linux学习笔记(16)shell基础之Bash变量

    1. 用户自定义变量 (1)变量设置规则 ① 变量名称可由字母.数字和下划线组成,但不能以数字开头: ② 变量的默认类型为字符串类型,如果要对数值运算,则必须指定变量类型为数值型: ③ 变量用等号连接 ...

  8. UVA232字符串处理

    #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> ...

  9. RMI的概念

    RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机上的对象可以调用另外一台计算机上的对象来 ...

  10. HDU 2222 Keywords Search (AC自动机)

    题意:给你一些模式串,再给你一串匹配串,问你在匹配串中出现了多少种模式串,模式串可以相同 AC自动机:trie树上进行KMP.首先模式串建立trie树,再求得失配指针(类似next数组),其作用就是在 ...