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.
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.
0
0
3
1
2
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