您的位置:首页 > 其它

【结论】升序逆序对

2016-07-13 20:07 197 查看
求法:

1、归并排序

#include<iostream>
#include<cstdio>
using namespace std;

int a[10003],a1[10003];
int ans=0;

void merge(int l,int mid,int r)
{
int i=l,k=l,j=mid+1;
while(i<=mid&&j<=r)
{
if(a[i]<=a[j]) a1[k++]=a[i++];// <
else
{
a1[k++]=a[j++];
ans+=mid-i+1;
}
}
while(i<=mid) a1[k++]=a[i++];
while(j<=r) a1[k++]=a[j++];
for(i=l;i<=r;i++) a[i]=a1[i];
}
void mergesort(int l,int r)
{
if(l<r)
{
int mid=(l+r)>>1;
mergesort(l,mid);
mergesort(mid+1,r);
merge(l,mid,r);
}
}

int main()
{
int n;scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
mergesort(1,n);
printf("%d",ans);
}


2、树状数组

(1)、当数字范围大于0且不大时,直接求

#include<cstdio>
#include<iostream>
using namespace std;
const int need=20003;//数字范围为20000;

int c[need];
int ans=0;

inline int lowbit(int s){return s&-s;}

int getsum(int x)
{
int cnt=0;
for(int i=x;i>0;i-=lowbit(i)) cnt+=c[i];
return cnt;
}

void modify(int x)
{
for(int i=x;i<need;i+=lowbit(i)) c[i]++;
}

int main()
{
int n;scanf("%d",&n);
for(int i=1,d;i<=n;i++)
{
scanf("%d",&d);
ans+=getsum(need-1)-getsum(d);// getsum(d-1)
modify(d);
}
printf("%d",ans);
}


(2)、离散化
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: