【算法笔记】 归并排序求逆序对 经典模板例题



题目描述

jzabc除了对多米诺骨牌感兴趣外,对赛车也很感兴趣。上个周末他观看了一场赛车比赛。他总是能想出许多稀奇的问题。某一时刻,他看到有n辆车(总是匀速行驶)在同一直线上,并且处在一个无限长度的直道上,而且n辆车有严格的先后之分。他通过特殊的器材测出了每一辆车的速度。那么问题出现了,如果有两辆车A车和B车,A车在B车的后面,并且A车的速度比B车的快,那么经过一段时间后,A车一定会超过B车。我们称之为一次超车。那么他想请你帮忙计算超车总数。我们记车道起点的坐标为0。没有两辆车的坐标相同。

输入格式

第一行,一个数n,车辆总数。
第二行至第n+1行,为n辆车的信息
每行有两个正整数x,y,x和y之间有一个空格
x为车的坐标,y为车的速度
0<x,y<=1000000000,

输出格式

一行,超车总数

样例数据

input

2
5 6
2 8

output

1

#include<bits/stdc++.h>
using namespace std;
long long N;
long long Ans=0;
long long cnt=0;
struct MERGEVAR
{
	long long Pos;
	long long V;
}Car[1000000]={};
long long NoUsed[10000000]={};
inline bool CMP(MERGEVAR X,MERGEVAR Y)
{
    return X.Pos<Y.Pos;  	
}
void MergeSort(long long Left,long long Right)
{
	if (Left==Right) return;
	long long L,R;
	long long temp=Left;
	if (Right-Left+1>=3)
	{
		long long Mid=(Left+Right)>>1;
		MergeSort(Left,Mid);
    	MergeSort(Mid+1,Right);
    	for (L=Left, R=Mid+1; L<=Mid&&R<=Right;)
    	{
		    if (Car[L].V>Car[R].V)
		    {
		    	NoUsed[temp++]=Car[R++].V;
		    	Ans+=Mid-L+1;
			}
			else NoUsed[temp++]=Car[L++].V;
    	}
    	if (R<=Right) 
		    for (;R<=Right;R++) NoUsed[temp++]=Car[R].V;
        else 
			for (;L<=Mid;L++) NoUsed[temp++]=Car[L].V;
    	for (long long i=Left;i<=Right;i++) Car[i].V=NoUsed[i];
    }
    else
    	if (Right-Left==1)
    		if (Car[Right].V<Car[Left].V) Ans++,swap(Car[Right].V,Car[Left].V);
    return;
}
int main()
{
	cin>>N;
	for (long long i=1;i<=N;i++) 
	    cin>>Car[i].Pos>>Car[i].V;
	sort(Car+1,Car+N+1,CMP);
	MergeSort( 1 , N );
	cout<<Ans;
	return 0;
} 


 



猜你喜欢

转载自blog.csdn.net/ronaldo7_zyb/article/details/80932534