hiho_1141

题目

    按顺序给出N个数字,求出所有的逆序对个数(逆序对指数字 Ai > Aj且 i < j) 
题目链接:hiho_1141 
    数据规模为 100000,必须使用O(nlogn)的算法来进行求解。下标i从0到N-1,依次求出数字Ai,在A[0, i-1]中比Ai大的数字个数K,将所有的K进行加和即可得到结果。 
    这种动态的排序+统计,使用treap。

实现

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<algorithm>
using namespace std;
struct Node{
	int val;
	int priority;
	int count;
	int sum;
	Node* childs[2];
	Node(int v = 0) :val(v){
		priority = rand();
		childs[0] = childs[1] = NULL;
		count = sum = 1;
	}
	void Update(){
		sum = count;
		if (childs[0])
			sum += childs[0]->sum;
		if (childs[1])
			sum += childs[1]->sum;
	}
};
struct Treap{
	Node* root;
	Treap(){
		root = NULL;
	}
	void Rotate(Node*& node, bool dir){
		Node* ch = node->childs[dir];
		node->childs[dir] = ch->childs[!dir];
		ch->childs[!dir] = node;
		node->Update();
		node = ch;
	}
	void Insert(Node*& node, int val){
		if (!node){
			node = new Node(val);
			return;
		}
		if (node->val == val){
			node->count++;
			node->sum++;
			return;
		}
		else{
			bool dir = node->val < val;
			Insert(node->childs[dir], val);
			if (node->childs[dir]->priority > node->priority){
				Rotate(node, dir);
			}
			node->Update();
		}
	}
	int Search(Node* node, int val){
		if (!node)
			return 0;
		if (node->val == val){
			if (node->childs[1])
				return node->childs[1]->sum;
			else
				return 0;
		}
		else if (node->val > val){
			return Search(node->childs[0], val) + (node->childs[1]? node->childs[1]->sum + node->count : node->count);
		}
		else
			return Search(node->childs[1], val);			
	}
};
int main(){
	Treap treap;
	int N;
	scanf("%d", &N);
	long long int count = 0;
	int val;
	for (int i = 0; i < N; i++){
		scanf("%d", &val);
		count += (treap.Search(treap.root, val));
		treap.Insert(treap.root, val);
	}
	printf("%lld
", count);
	return 0;
}
原文地址:https://www.cnblogs.com/gtarcoder/p/5689957.html