您的位置:首页 > 其它

sgu 180. Inversions (树状数组+离散化,第一道需要改模板的题目,好题)

2014-03-03 19:32 302 查看
1、/article/8682214.html

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
input: 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
[align=left]Write amount of such pairs. [/align]

Sample test(s)

Input
[align=left][/align]



[align=left]5 2 3 1 5 4 [/align]



[align=left][/align]
[align=left][/align]

Output
[align=left][/align]



[align=left]3 [/align]



[align=left][/align]
[align=left][/align]
5、AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 65540
#define ll long long
int n;
int c
;
struct node
{
int id;
int v;
}a
;
node b
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: