Reverse order right (not understood)

Posted by aashcool198 on Mon, 15 Jul 2019 20:33:08 +0200

Title:

Alice is a very pleasant person! He always learns some questions he doesn't understand, and then comes up with many strange questions. These days, Alice is immersed in the happiness of reverse order pair. He has learned how to find reverse order pair logarithm, dynamically maintain reverse order pair logarithm and so on. He thinks it is too hard for you to pursue these questions. After a day's thinking and perfection, Alice finally comes up with a topic which he thinks is similar:

There is a binary tree with 2n-1 nodes, which has exactly n leaf nodes, and an integer is written on each node. If you write down the number of all leaf nodes of the tree from left to right, you get a sequence a[1]... a[n]. Now we want to minimize the number of inverse logarithms in this sequence, but the only operation is to select a non-leaf node on the tree and exchange its left and right subtrees. He can do it any number of times. Under the optimal scheme, the minimum number of inverse logarithms of the sequence is found.

Alice himself has come up with the right answer to the question. He intends to share it with you. He asks you to finish it in the shortest possible time.

Input format

The first line is an integer n.

For each line below, count x.

If x=0, it means that the node is not a leaf node. It reads the information of its left and right children down recursively. If x_0, it means that the node is a leaf node with weight X.

Output format
Output an integer indicating the minimum number of reverse pairs.
sample input
3
0
0
3
1
2
sample output

1

Reference code: http://blog.csdn.net/enjoying_science/article/details/44114035

#include<cstdio> 
#include<iostream>
using namespace std;
#define ForD(i,n) for(int i = n;i ;i --)
#define F (100000007)
#define MAXN (2*200000 + 10)
long long mul(long long a,long long b)
{
	return (a * b) % F;
}
long long add(long long a,long long b)
{
	return (a + b) % F;
}
long long sub(long long a,long long b)
{
	return (a - b + (a - b) / F * F + F) % F;
}
int n,root = 0;
struct node
{
	int fa,ch[2],size,c;
	node():size(0),c(0){ch[0] = ch[1] = fa = 0;}
}a[MAXN];
int tail = 0;
int q[MAXN],size;

void update(int x)
{
	a[x].size = a[a[x].ch[0]].size + a[a[x].ch[1]].size + (a[x].c > 0);//Update the size of parent node 
}

void pushdown(int x)
{
	a[a[x].ch[0]].fa = a[a[x].ch[1]].fa = x;//Find the parent node a[x].fa = 0 -- the root node 
}
void build(int &x) 
{
	if(!x)	x = ++ tail;
	scanf("%d",&a[x].c);
	if(a[x].c == 0) //Not leaves 
	{
		build(a[x].ch[0]);//Construction of left subtree 
		build(a[x].ch[1]);//Build right subtree 
		update(x);
		pushdown(x);//Connecting Node and Leaf 
	}else a[x].size = 1;
//	Court < <"______________ x < endl; I thought it was a precedent traversal, but the output of X was ____________________ 
}

void rotate(int x)
{
	int y = a[x].fa,z = a[y].fa;
	bool p = a[y].ch[0] == x;
	if(z)
	{
		if(a[z].ch[0] == y) a[z].ch[0] = x;
		else a[z].ch[1] = x;
	}
	a[x].fa = z,a[y].fa = x;
	if(a[x].ch[p]) a[a[x].ch[p]].fa = y;
	a[y].ch[p^1] = a[x].ch[p];
	a[x].ch[p] = y;
	update(y);
}

void splay(int x)
{
	while(a[x].fa)
	{
		int y = a[x].fa,z = a[y].fa;
		if(z)
			if((a[y].ch[0] == x) ^ (a[z].ch[0] == y)) rotate(x);
			else rotate(y);
		rotate(x);
	}
	update(x);
}

void ins(long long &tot,int x,int y)
{
	a[x].size ++;
	if(a[y].c <= a[x].c)
	{
		if(a[x].ch[0]) ins(tot,a[x].ch[0],y);
		else a[y].fa = x,splay(a[x].ch[0] = y);
	}
	else
	{
		tot += a[a[x].ch[0]].size + (a[x].c > 0);
		if(a[x].ch[1]) ins(tot,a[x].ch[1],y);
		else a[y].fa = x,splay(a[x].ch[1] = y);
	}
}

void clac(int x,int y)
{
	if(a[y].ch[0]) clac(x,a[y].ch[0]);
	if(a[y].c) q[++size] = y;
	if(a[y].ch[1]) clac(x,a[y].ch[1]);
}

long long merge(bool &lor,int z)
{
	int x = a[z].ch[0],y = a[z].ch[1];
	if(a[x].size < a[y].size)
	swap(x,y);
	
	a[x].fa = 0;
	a[y].fa = 0;
	q[1] = y;
	size = 0;
	clac(x,y);
	long long tot = 0;
	ForD(i,size)
	{
		int now = q[i];
		a[now].ch[0] = a[now].ch[1] = a[now].fa = 0;
		a[now].size = 1;
		ins(tot,x,now);
		x = now;
	}
	a[x].fa = z;
	a[z].ch[0] = 0,a[z].ch[1] = x;
	return tot;
}

long long qur(int &x) 
{
	if(a[x].c) return 0;//cotyledon
	else
	{
		long long lson = a[a[x].ch[0]].size,rson = a[a[x].ch[1]].size,
		ls = qur(a[x].ch[0]),rs = qur(a[x].ch[1]);
		bool lor = 0;
		long long ms = merge(lor,x);
		return ls + rs + min(lson*rson - ms,ms);
	 } 
}

int main()
{
	scanf("%d",&n);
	build(root);
	//root = 1;
	cout << qur(root) << endl;
	return 0;
}


In order to find inverse order pairs, merge order is generally adopted. http://blog.csdn.net/u010128136/article/details/52852093