H 逆序的人生
给定一个n个元素的数组,这个数组由1…n的一个排列,输出其逆序对数。
输入:正整数n,然后输入n个元素(n<=100000)
输出:一行,表示其逆序数(int范围内)。
样例输入:
5
4 3 1 5 2
样例输出:
6
开始傻傻地想要暴力。。。。犯糊涂了。。。肯定超时的。
用树状数组的话可以减少复杂度,直接套用模板,便可以得出。
关键部分:ans += a[i]-query(a[i]); //这里是关键,query(a[i])此时返回的结果是将a[i]在这个状态下比a[i]小的个数(包括a[i]),很明显我们是按照从前往后的先后顺序插入的,那么这个值就求的了他前面比它小的数,包括他自己,那么用它自己减去这个值就得到了后面比它小的个数了。。。
#include <iostream>
#include <stdio.h>
#include <memory.h>
using namespace std;
const int maxn=100010;
int n,a[maxn],in[maxn];
int lowbit(int t)
{
return t&(-t);
}
void modify(int pos,int num)
{
while(pos<=n)
{
in[pos]+=num;
pos+=lowbit(pos);
}
}
int query(int end)
{
int sum=0;
while(end>0)
{
sum+=in[end];
end-=lowbit(end);
}
return sum;
}
int main()
{
int i,j,k,l,q,ans;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
in[i]=0;
ans=0;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
modify(a[i],1);
ans+=a[i]-query(a[i]);
}
printf("%d\n",ans);
}
return 0;
}