【POI 2011】Tree Rotations

【题目】

传送门

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.

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).

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


【分析】

题目意思就去 BZOJ 上看吧,我觉得我胡不清楚

还有这道题读入有点迷啊

首先,不论是那种遍历,遍历到叶节点的顺序是不变的,画个图的话,顺序就是叶节点从左到右的顺序

每个点的子树的逆序对个数 = 其左子树的逆序对个数 + 其右子树的逆序对的个数 + 不同子树的逆序对个数

这就有点像分治了,对于前两个,直接递归操作,现在考虑如何最小化第三个

其实思路也简单,就是比较不交换的逆序对个数交换的逆序对个数,取个 m i n min 就行

而这一步的话,可以选择用线段树合并实现

时间复杂度 O ( n l o g &ThickSpace; n ) (n*log\;n)


【代码】

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1000005
using namespace std;
long long L,R;
int n,rt,tot,cnt;
int val[N],root[N],son[N][2],size[N*40],lc[N*40],rc[N*40];
void Read(int &now)
{
	now=++cnt;
	scanf("%d",&val[now]);
	if(!val[now])
	{
		Read(son[now][0]);
		Read(son[now][1]);
	}
}
void build(int &root,int l,int r,int val)
{
	root=++tot;
	size[root]=1;
	if(l==r)  return;
	int mid=(l+r)>>1;
	if(val<=mid)  build(lc[root],l,mid,val);
	else  build(rc[root],mid+1,r,val);
}
int Merge(int x,int y)
{
	if(!x)  return y;
	if(!y)  return x;
	size[x]+=size[y];
	L+=1ll*size[lc[x]]*size[rc[y]];
	R+=1ll*size[rc[x]]*size[lc[y]];
	lc[x]=Merge(lc[x],lc[y]);
	rc[x]=Merge(rc[x],rc[y]);
	return x;
}
long long dfs(int x)
{
	long long ans=0;
	if(!val[x])
	{
		ans=dfs(son[x][0])+dfs(son[x][1]);
		L=R=0,root[x]=Merge(root[son[x][0]],root[son[x][1]]);
		ans+=min(L,R);
	}
	else  build(root[x],1,n,val[x]);
	return ans;
}
int main()
{
	scanf("%d",&n);
	Read(rt);
	printf("%lld",dfs(rt));
	return 0;
}

猜你喜欢

转载自blog.csdn.net/forever_dreams/article/details/83475716