顾名思义,例如:有序列 2 4 3 1 那么 2 4, 2 1,4 1, 3 1为逆序对,逆序数为4。
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <functional>
#include <iomanip>
#include <algorithm>
#include <limits>
//#include <ext/hash_map>
//using namespace __gnu_cxx;
typedef long long LL;
typedef unsigned long long ULL;
#define RDI(x) scanf("%d",&x)
#define RDI_2(x,y) scanf("%d%d",&x,&y)
#define RDD(x) scanf("%lf",&x)
#define RDD_2(x,y) scanf("%lf%lf",&x,&y)
#define RDL(x) scanf("%lld",&x)
#define RDL_2(x,y) scanf("%lld%lld",&x,&y)
#define RDS(x) scanf("%s",x)
#define RDS_2(x,y) scanf("%s%s",x,y)
#define PUTI(x) printf("%d",x)
#define PUTL(x) printf("%lld",x)
#define PUTF(x) printf("%f",x)
#define PUTC(x) putchar(x)
#define LINE putchar('\n')
#define SPACE putchar(' ')
#define REP(i,x) for(int i=0;i<int(x);++i)
#define REP_1(i,x) for(int i=1;i<=int(x);++i)
#define REP_C(i,x) for(i=0;i<int(x);++i)
#define REP_E(i,x,y) for(int i=0;i<int(x);++i,y)
#define REP_1_E(i,x,y) for(int i=1;i<=int(x);++i,y)
#define REP_1_C(i,x) for(i=1;i<=int(x);++i)
#define FOR_EDGE(i,x) for(int i=head[x];~i;i=edge[i].next)
#define FOR_EDGE2(x,i,y) for(int i=head[x][y];~i;i=edge[i].next)
#define FOR(i,a,b) for(int i=int(a);i<=int(b);++i)
#define FORD(i,a,b) for(int i=int(a);i>=int(b);--i)
#define DWN(i,x) for(int i=int(x-1);i>=0;--i)
#define DWN_1(i,x) for(int i=int(x);i>0;--i)
#define FIL(x,v) memset(x,v,sizeof(x))
#define CLR(x) memset(x,0,sizeof(x))
#define ALL(x) x.begin(),x.end()
#define p_queue priority_queue
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define fst first
#define snd second
#define x first
#define y second
#define mp(x,y) make_pair(x,y)
//#define check(x) printf("%s=%d\n",#x,x)
using namespace std;
template<typename T>
T gcd(T a, T b){ return b == 0 ? a : gcd(b, a%b); }
template<typename T>
T lcm(T a, T b){ return a / gcd(a, b)*b; }
template<typename T>
T ext_gcd(T a, T b, T& x, T& y)
{
if (b == 0)
{
x = 1, y = 0;
return a;
}
int d = ext_gcd(b, a%b, y, x);
y -= x*(a / b);
return d;
}
template<typename T>
T quick_pow(T a, T b)
{
if (b == 0) return 1;
T p = quick_pow(a, b >> 1);
p = p*p;
if (b & 1) p =p*a;
return p;
}
double combination(int n, int r)
{
if (r<n - r) return combination(n, n - r);
double s = 1.0;
REP_1(i, n - r) s *= (r + i), s /= i;
return s;
}
template<typename T>
inline void read(T& v)
{
T ret = 0, sgnv = 1;
char p;
while (!isdigit(p = getchar())) if (p == '-') sgnv = -1;
do{
ret = (ret << 3) + (ret << 1) + p - '0';
} while (isdigit(p = getchar()));
v = sgnv*ret;
}
const double eps=1e-8;
inline int sgn(double x){ return (x>-eps)-(x<eps); }
const int mod=1000000007;
//const int INF = numeric_limits<int>::max();
const int INF = 0x7f7f7f7f;
//const int INFCELL = 0x7f;
#define MAX 1000+5
#define lucknum 19960308
#define ONLINE_JUDGE
void merge(int *a, int *t, int leftPos, int rightPos, int rightEnd, int &ans)
{
int leftEnd = rightPos - 1;
int elementsNum = rightEnd - leftPos + 1;
int tmpPos = leftPos;
while(leftPos <= leftEnd && rightPos <= rightEnd)
{
if(a[rightPos] < a[leftPos]) //此时产生逆序数
{
ans += leftEnd - leftPos + 1;
t[tmpPos++] = a[rightPos++];
}
else
t[tmpPos++] = a[leftPos++];
}
while(leftPos <= leftEnd) t[tmpPos++] = a[leftPos++];
while(rightPos <= rightEnd) t[tmpPos++] = a[rightPos++];
for(int i = 0; i < elementsNum; ++i, --rightEnd)
a[rightEnd] = t[rightEnd];
}
void mergeSort(int *a, int *t, int left, int right, int &ans)
{
if(left < right)
{
int center = (left + right) >> 1;
mergeSort(a, t, left, center, ans);
mergeSort(a, t, center + 1, right, ans);
merge(a, t, left, center + 1, right, ans);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
int a[MAX], t[MAX], n, ans = 0;
RDI(n);
REP(i, n) RDI(a[i]);
mergeSort(a, t, 0, n - 1, ans);
PUTI(ans);
return 0;
}