逆序数

顾名思义,例如:有序列 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值