求逆序数#no

来源:互联网 发布:c语言中cos是什么意思 编辑:程序博客网 时间:2024/05/04 18:27
今天做了下POJ2299,逆序数的2种方法:


1.归并排序法:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;long long  ans;int c[500100];int a[500100];void merge(int l,int m,int r){    int i = l,j = m+1;    int cnt = 0;    while(i<=m && j<=r)    {        if(a[i]<a[j]){c[cnt++] = a[i];i++;}        else        {             ans += m-i+1;             c[cnt++] = a[j];             j++;        }    }    //cout << ans << endl;    while(i<=m){c[cnt++] = a[i];i++;}    while(j<=r){c[cnt++] = a[j];j++;}    //cout << cnt << endl;    for(i=l;i<=r;i++)        a[i] = c[i-l];}void mergesort(int l,int r){    if(l<r)    {        int m  = (r+l)>>1;        mergesort(l,m);        mergesort(m+1,r);        merge(l,m,r);    }}int main(){    //freopen("input.txt","r",stdin);    int n;    while(scanf("%d",&n),n)    {        ans = 0;        for(int i=0;i<n;i++)            scanf("%d",&a[i]);        mergesort(0,n-1);        printf("%I64d\n",ans);    }    return 0;}




2.树状数组:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define lowbit(x) (x&-x)struct node{    int val,no;};node a[500100];int aa[500100];int c[500100];int n;void update(int x,int d){    for(int i=x;i<=n;i+=lowbit(i))        c[i]+=d;}int getsum(int x){    int sum = 0;    for(int i=x;i>0;i-=lowbit(i))        sum += c[i];    return sum;}bool cmp(const node& n1,const node& n2){    return n1.val < n2.val;}int main(){    while(scanf("%d",&n),n)    {        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i].val);            a[i].no = i;        }        sort(a+1,a+n+1,cmp);        for(int i=1;i<=n;i++)            aa[a[i].no] = i;        memset(c,0,sizeof(c));        long long ans = 0;        for(int i=1;i<=n;i++)        {            update(aa[i],1);            ans += i-getsum(aa[i]);        }        printf("%I64d\n",ans);    }    return 0;}

原创粉丝点击