1、http://blog.csdn.net/sdjzping/article/details/20381665
2、题目大意:
有n个数字,定义i<j并且a[i]>a[j]这样的一对数为逆序对,求这个数中有多少逆序对,
3、题目分析
看着题目很简单,但是n=65537,两重for循环找必超时,所以想到了用树状数组,但是交了好几遍都错了,runtime error,原因就是数组中的数字可以到达10^9,数组肯定要超内存,此题需要用到离散化,但是数字之间可能有重复,这一点没考虑到,有wrong 了好几遍,不过终于是改对了,。
4、题目:
180. Inversions
time limit per test: 0.25 sec.
memory limit per test: 4096 KB
memory limit per test: 4096 KB
input: standard
output: standard
output: standard
There are N integers (1<=N<=65537) A1, A2,.. AN (0<=Ai<=10^9). You need to find amount of such pairs (i, j) that 1<=i<j<=N and A[i]>A[j].
Input
The first line of the input contains the number N. The second line contains N numbers A1...AN.
Output
Write amount of such pairs.
Sample test(s)
Input
5 2 3 1 5 4
Output
3
5、AC代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 65540
#define ll long long
int n;
int c[N];
struct node
{
int id;
int v;
}a[N];
node b[N];
int cmp(node a,node b)
{
return a.v<b.v;
}
int cmp1(node a,node b)
{
return a.id<b.id;
}
int lowbit(int i)
{
return i&(-i);
}
void update(int x,int v)
{
for(int i=x;i<=n;i+=lowbit(i))
{
c[i]+=v;
}
}
ll getsum(int x)
{
ll sum=0;
//此处注意需要计算的是比自己小的,所以不包含自己
for(int i=x-1;i>=1;i-=lowbit(i))
{
sum+=c[i];
}
return sum;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].v);
a[i].id=i;
}
sort(a+1,a+n+1,cmp);
a[0].v=-1;
int k=1;
//注意离散化的时候考虑相等的情况
for(int i=1;i<=n;i++)
{
if(a[i].v!=a[i-1].v)
{
b[i].id=a[i].id;
b[i].v=k++;
}
else
{
b[i].id=a[i].id;
b[i].v=b[i-1].v;
}
}
sort(b+1,b+n+1,cmp1);
ll sum=0;
for(int i=n;i>=1;i--)
{
sum+=getsum(b[i].v);
update(b[i].v,1);
}
printf("%lld\n",sum);
}
return 0;
}