POJ 2299 逆序对(归并排序)

来源:互联网 发布:淘宝注册会员名大全 编辑:程序博客网 时间:2024/06/10 19:04

题意:两两相邻的元素可以交换,问最小交换次数使得数列为升序。

思路:归并排序分治法。看到琦神又用了树状数组的方法求。

#include <iostream>#include <cstdio>#include <fstream>#include <algorithm>#include <cmath>#include <deque>#include <vector>#include <queue>#include <string>#include <cstring>#include <map>#include <stack>#include <set>#define PI acos(-1.0)#define mem(a,b) memset(a,b,sizeof(a))#define sca(a) scanf("%d",&a)#define sc(a,b) scanf("%d%d",&a,&b)#define pri(a) printf("%d\n",a)#define lson i<<1,l,mid#define rson i<<1|1,mid+1,r#define MM 100004#define MN 1008#define INF 100000007#define eps 1e-7using namespace std;typedef long long ll;typedef unsigned long long ULL;ll mergesort(int *a,int n){    if(n==1) return 0;    int mid=n/2;    ll sum=mergesort(a,mid)+mergesort(a+mid,n-mid);    int *b=new int[n];    memcpy(b,a,n*sizeof(int));    for(int i1=0,i2=mid,i=0; i1<mid||i2<n; i++)    {        if(i2==n)        {            a[i]=b[i1];            i1++;            sum+=i2-mid;        }        else if(i1==mid) a[i]=b[i2],i2++;        else if(b[i1]<b[i2])        {            a[i]=b[i1];            i1++;            sum+=i2-mid;        }        else a[i]=b[i2],i2++;    }    delete []b;    return sum;}int main(){    static int a[500005];    int n,i;    while(sca(n)&&n)    {        for(i=0; i<n; i++)            sca(a[i]);        ll sum=mergesort(a,n);        printf("%lld\n",sum);    }    return 0;}


0 0