洛谷1908逆序对

来源:互联网 发布:手机充电加速软件 编辑:程序博客网 时间:2024/06/04 18:57

题目描述

猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。

输入输出格式

输入格式:

第一行,一个数n,表示序列中有n个数。

第二行n个数,表示给定的序列。

输出格式:

给定序列中逆序对的数目。

输入输出样例

输入样例#1:
65 4 2 6 3 1
输出样例#1:
11






说明

对于50%的数据,n≤2500

对于100%的数据,n≤40000。

利用归并排序解决

代码如下:

#include <bits/stdc++.h>#define maxn 40010#define INF 0x7f7f7f7f#define ll long longusing namespace std;int a[maxn], b[maxn], c[maxn], d[maxn];void merge_sort( int l, int r){if ( l == r)return;int m = ( l + r) / 2;merge_sort( l, m);merge_sort( m + 1, r);int x = m - l + 1, y = r - m;int j, k, t;j = l, k = m + 1, t = 0;while ( j <= m && k <= r){if ( a[j] <= a[k]){d[t] = a[j];b[t++] = a[j++];}else{c[k] += m - j + 1;d[t] = c[k];b[t++] = a[k++];}}while ( j <= m){d[t] = c[j];b[t++] = a[j++];}while ( k <= r){d[t] = c[k];b[t++] = a[k++];}for ( int i = l; i <= r; i++){a[i] = b[i - l];}}int main(){int n;scanf( "%d", &n);for ( int i = 0; i < n; i++){scanf( "%d", &a[i]);} int s = 0;merge_sort( 0, n - 1);for ( int i = 0; i < n; i++){s += c[i];}printf( "%d\n", s);return 0;}




0 0
原创粉丝点击