SGU_180_Inversions

来源:互联网 发布:怎么装ubuntu系统 编辑:程序博客网 时间:2024/06/14 14:05

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
Write amount of such pairs.

Sample test(s)

Input
5 2 3 1 5 4
Output
3
[submit]
[forum]

Author:Stanislav AngelyukResource:Saratov ST team Spring Contest #1Date:18.05.2003




乍一看是poj2299

但是有一点这个问题输入并没有保证数字不相同

所以做坐标变换的时候应该在比较值的同时比较一下位置信息

#include <iostream>#include <stdio.h>#include <algorithm>using namespace std;const int M=65540;int tree[M];struct NODE{    int v,p;}node[M];bool cmp1(NODE a,NODE b){    if(a.v==b.v)        return a.p<b.p;    //值相同的时候比较下位置信息,这样把相同值离散成不同的小的值得时候    return a.v<b.v;        //不会产生同样数值变成的大的数字,位置到前面去影响结果}bool cmp2(NODE a,NODE b){    return a.p<b.p;}int lowbit(int x){    return x&(-x);}int getsum(int x){    int s=0;    for(int i=x;i;i-=lowbit(i))        s+=tree[i];    return s;}void add(int x,int v){    for(int i=x;i<M;i+=lowbit(i))        tree[i]+=v;}int main(){    int n;    long long co=0;    scanf("%d",&n);    for(int i=0;i<n;i++)    {        scanf("%d",&node[i].v);        node[i].p=i;    }    sort(node,node+n,cmp1);    for(int i=0;i<n;i++)    {        node[i].v=i+1;    }    sort(node,node+n,cmp2);    for(int i=0;i<n;i++)    {        co+=i-getsum(node[i].v-1);        add(node[i].v,1);    }    printf("%I64d\n",co);    return 0;}


0 0