[POI2011] ROT-Tree Rotations solution to a problem

Face questions

This question first glance are not starting from dp, then start from the data structure! ;

First you have to be right value segment tree and tree line consolidation.

Then you need to know:

 

For any node, switching left and right subtrees of the current node and all of the foregoing no effect .

 

Because this is a preorder traversal : root -> left sub-tree -> right subtree. It can be seen exchanging left and right subtrees no effect on the previous node .

We know, commutator tree will only Dui across the left and right subtrees of the reverse impact on this situation. Therefore, we only need to merge tree line statistical exchange sub-tree of the number ans1 reverse and reverse exchange not for the number of sub-tree ans1, taken during min (ans1, ans2) accumulate to answer on the line.

Every merger tree line, the recursion to all nodes except the leaf nodes, should reverse the accumulation of the number of U, v .

Note that we are able to calculate this it is because no matter how about the son of exchange, reverse current are only part of the impact on the number, without affecting the value of the depth shallower node.

Note To reclaim memory, otherwise it will MLE

#include <bits/stdc++.h>
#define inc(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;
int n;
class node{
	public:
	long long lson,rson,sum;
}tree[200010*13];
long long ans1,ans2;
int now=0;	
int merge(int x,int y,int l,int r){
	if(!x) return y;
	if(!y) return x;
	if(l==r){
		tree[x].sum+=tree[y].sum;
		return x;
	}
	ans1+=tree[tree[x].rson].sum*tree[tree[y].lson].sum;
	ans2+=tree[tree[x].lson].sum*tree[tree[y].rson].sum;
	int mid=(l+r)>>1;
	tree[x].lson=merge(tree[x].lson,tree[y].lson,l,mid);
	tree[x].rson=merge(tree[x].rson,tree[y].rson,mid+1,r);
	tree[x].sum=(tree[tree[x].lson].sum+tree[tree[x].rson].sum);
	return x;
}
int build(int l,int r,int goal){
	int pos=++now;
	tree[pos].sum++;
	if(l==r) return pos;
	int mid=(l+r)>>1;
	if(goal<=mid){
		tree[pos].lson=build(l,mid,goal);
	}
	else{
		tree[pos].rson=build(mid+1,r,goal);
	}
	return pos;
}
long long ans=0;
int read()
{
	int pos,v;
	scanf("%d",&v);
	if(v==0){
		int lson=read(),rson=read();
		ans1=0; ans2=0;
		pos=merge(lson,rson,1,n);
		ans+=min(ans1,ans2);
	}
	else{
		return pos=build(1,n,v);
	}
	return pos;
}
int main()
{
	scanf("%d",&n);
	read();
	cout<<ans;
} 

 

Guess you like

Origin www.cnblogs.com/kamimxr/p/11779475.html