线段树的合并..对于一个点x, 我们只需考虑是否需要交换左右儿子, 递归处理左右儿子.

 #include<bits/stdc++.h>

 using namespace std;

 #define M(l, r) (((l) + (r)) >> 1)

 typedef long long ll;

 const int maxn = ;

 int N, V[maxn], lc[maxn], rc[maxn], n = ;

 struct Node *null, *pt;
struct Node {
Node *l, *r;
int cnt;
Node() : cnt() {
l = r = null;
}
inline void update() {
cnt = l->cnt + r->cnt;
}
void* operator new(size_t) {
return pt++;
}
} pool[maxn * ], *root[maxn]; void init() {
pt = pool;
null = new(Node);
null->l = null->r = null;
} int v;
void build(Node* t, int l, int r) {
t->cnt = ;
if(r > l) {
int m = M(l, r);
v <= m ? build(t->l = new(Node), l, m) : build(t->r = new(Node), m + , r);
}
} ll cnt0, cnt1, ans = ; Node* merge(Node* L, Node* R) {
if(L == null) return R;
if(R == null) return L;
cnt0 += ll(L->r->cnt) * R->l->cnt;
cnt1 += ll(L->l->cnt) * R->r->cnt;
L->l = merge(L->l, R->l);
L->r = merge(L->r, R->r);
L->update();
return L;
} void read(int x) {
scanf("%d", V + x);
if(!V[x]) {
read(lc[x] = n++); read(rc[x] = n++);
}
} void work(int x) {
if(!~x) return;
work(lc[x]); work(rc[x]);
if(!V[x]) {
cnt0 = cnt1 = ;
if(!~lc[x])
root[x] = root[rc[x]];
else if(!~rc[x])
root[x] = root[lc[x]];
else
root[x] = merge(root[lc[x]], root[rc[x]]);
ans += min(cnt0, cnt1);
}
} int main() { init();
memset(lc, -, sizeof lc); memset(rc, -, sizeof rc);
scanf("%d", &N);
n = ; read(n++); for(int i = ; i < n; i++) if(V[i]) {
v = V[i];
build(root[i] = new(Node), , N);
}
work();
cout << ans << "\n"; return ;
}

2212: [Poi2011]Tree Rotations

Time Limit: 20 Sec  Memory Limit: 259 MB
Submit: 548  Solved: 195
[Submit][Status][Discuss]

Description

Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some interesting features: The tree consists of straight branches, bifurcations and leaves. The trunk stemming from the ground is also a branch. Each branch ends with either a bifurcation or a leaf on its top end. Exactly two branches fork out from a bifurcation at the end of a branch - the left branch and the right branch. Each leaf of the tree is labelled with an integer from the range . The labels of leaves are unique. With some gardening work, a so called rotation can be performed on any bifurcation, swapping the left and right branches that fork out of it. The corona of the tree is the sequence of integers obtained by reading the leaves' labels from left to right. Byteasar is from the old town of Byteburg and, like all true Byteburgers, praises neatness and order. He wonders how neat can his tree become thanks to appropriate rotations. The neatness of a tree is measured by the number of inversions in its corona, i.e. the number of pairs(I,j), (1< = I < j < = N ) such that(Ai>Aj) in the corona(A1,A2,A3…An).  The original tree (on the left) with corona(3,1,2) has two inversions. A single rotation gives a tree (on the right) with corona(1,3,2), which has only one inversion. Each of these two trees has 5 branches. Write a program that determines the minimum number of inversions in the corona of Byteasar's tree that can be obtained by rotations.

现在有一棵二叉树,所有非叶子节点都有两个孩子。在每个叶子节点上有一个权值(有n个叶子节点,满足这些权值为1..n的一个排列)。可以任意交换每个非叶子节点的左右孩子。
要求进行一系列交换,使得最终所有叶子节点的权值按照遍历序写出来,逆序对个数最少。

Input

In the first line of the standard input there is a single integer (2< = N < = 200000) that denotes the number of leaves in Byteasar's tree. Next, the description of the tree follows. The tree is defined recursively: if there is a leaf labelled with ()(1<=P<=N) at the end of the trunk (i.e., the branch from which the tree stems), then the tree's description consists of a single line containing a single integer , if there is a bifurcation at the end of the trunk, then the tree's description consists of three parts: the first line holds a single number , then the description of the left subtree follows (as if the left branch forking out of the bifurcation was its trunk), and finally the description of the right subtree follows (as if the right branch forking out of the bifurcation was its trunk).

第一行n
下面每行,一个数x
如果x==0,表示这个节点非叶子节点,递归地向下读入其左孩子和右孩子的信息,
如果x!=0,表示这个节点是叶子节点,权值为x

1<=n<=200000

Output

In the first and only line of the standard output a single integer is to be printed: the minimum number of inversions in the corona of the input tree that can be obtained by a sequence of rotations.

一行,最少逆序对个数

Sample Input

3
0
0
3
1
2

Sample Output

1

HINT

 

Source

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

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

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

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

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

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

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

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

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

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

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

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

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

  7. bzoj 2212: [Poi2011]Tree Rotations

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

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

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

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

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

随机推荐

  1. 为什么每个程序员都应该用Mac OS X?

    1.Mac OS X 是基于 Unix 的.这一点太重要了,尤其是对开发人员,至少对于我来说很重要,这意味着Unix 下一堆好用的工具都可以随手捡到.如果你是个 windows 开发人员,我想你会在 ...

  2. iOS 基于Socket 的 C/S 网络通信结构(下一个)

    以前实现简单 Server 程序,服务端通过 void WriteStreamClientCallBack(CFWriteStreamRef stream, CFStreamEventType eve ...

  3. 《TCP/IP详细说明》读书笔记(17章)-TCP传输控制协定

    1.TCP的服务 在一个TCP连接中.仅有双方进行彼此通信. TCP通过下列方式来提供可靠性: 1)应用数据被切割成TCP觉得最适合发送的数据块. 这和UDP全然不同,应用程序产生的数据报长度保持不变 ...

  4. pre标签 首行会自动换行解决方案

    利用pre标签可以 解决文本文档里面的空格及换行在页面上不显示的方案, 自行换行 加 white-space: pre-wrap; word-wrap: break-word; 英文字母换行 word ...

  5. linkbutton.js

    jquery.linkbutton.js /** * linkbutton - jQuery EasyUI * * Licensed under the GPL: * http://www.gnu.o ...

  6. centos6.5配置163的yum源

    CentOS系统自带的更新源的速度实在是慢,为了让CentOS6使用速度更快的YUM更新源,可以选择163(网易)的更新源. 1.下载repo文件 wget http://mirrors.163.co ...

  7. [LeetCode]题解(python):021-Merge Two Sorted Lists

    题目来源: https://leetcode.com/problems/merge-two-sorted-lists/ 题意分析: 题目给出两个排好序的链表,将这两个链表整合成一个新的有序的链表. 题 ...

  8. 循环结构中break、continue、return和exit的区别

    1. break break语句的使用场合主要是switch语句和循环结构.在循环结构中使用break语句,如果执行了break语句,那么就退出循环,接着执行循环结构下面的第一条语句.如果在多重嵌套循 ...

  9. [Android文档翻译]设备兼容性

    原文地址:Device Compatibility Android设计于运行在多种不同类型的设备上,从手机.平板到电视.作为一名开发者,设备的涵盖范围为你的app提供了广大的潜在用户.为了让你的app ...

  10. ZOJ 1825 compoud words

    题目大意:输入一串递增的单词序列,需要找出符合条件的单词递增输出,条件是:将一个单词拆成左右两个单词后,能在输入中找到这两个单词.例如单词 alien,可以拆成 a 和 lien,而输入中刚好同时有a ...