原题链接:点击打开链接
【一】 利用 树状数组 离散化 之后求逆序数:
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 1000000
long long c[N+1],aaa[N+1];
struct sb
{
int x;
int y;
}yi[N+1];
bool cmp(struct sb t1,struct sb t2)
{
if(t1.x!=t2.x)
return t1.x<t2.x;
else
return t1.y<t2.y;
}
int lowbit (int a)
{
return a&(-a);
}
void add(int a)
{
while(a<N+1)
{
c[a]+=1;
a+=lowbit(a);
}
}
int Sum(int a)
{
int SUM=0;
while(a>0)
{
SUM+=c[a];
a-=lowbit(a);
}
return SUM;
}
int main()
{
int a,b,n,m;
scanf("%d",&n);
while(n--)
{
long long sum=0;
memset(c,0,sizeof(c));
scanf("%d",&m);
for(a=1;a<=m;a++)
{
scanf("%lld",&yi[a].x);
yi[a].y=a;
}
std::sort(yi+1,yi+m+1,cmp);//离散化。。。
for(a=1;a<=m;a++)
aaa[yi[a].y]=a;
for(a=1;a<=m;a++)
{
add(aaa[a]);
sum+=(a-1-Sum(aaa[a]-1));
}
printf("%lld\n",sum);
}
}
【二】 利用 归并排序 求逆序数:
代码:
#include<stdio.h>
#include<string.h>
#define max 1000008
long long count;
long long a[max],t[max];
void merge_sort(long long *a, long long x,long long y ,long long *t)
{
if(y-x>1)
{
long long m=x+(y-x)/2;//h划分
long long p=x,q=m,i=x;
merge_sort(a,x,m,t);//递归求解
merge_sort(a,m,y,t);
while(p<m||q<y)
{
if(q>=y||(p<m&&a[p]<=a[q]))
t[i++]=a[p++];
else
{
t[i++]=a[q++];
count+=(m-p);//计数。。
}
}
for(i=x;i<y;i++)
a[i]=t[i];
}
}
int main()
{
long long n,m;
scanf("%lld",&n);
while(n--)
{
scanf("%lld",&m);
memset(a,0,sizeof(a));
memset(t,0,sizeof(t));
long long b;
count=0;
for(b=0;b<m;b++)
scanf("%lld",&a[b]);
merge_sort(a,0,m,t);
printf("%lld\n",count);
}
}