SGU180 - Inversions

题目大意

给定N个数,a1,a2,3,a4..an,要求你求出这样的对数:i<=i<j<=n并且a[i]>a[j]。

题解

就是逆序对问题。。。果断用树状数组做,数据有点大0<=Ai<=10^9,需要进行离散化,离散的时候注意会有相同的数,最先没注意这个,提交上去第二组数据就WA了。

代码

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#define MAXN 70000

using namespace std;

typedef struct

{

    long id;

    long t;

} NODE;

NODE a[MAXN];

long long c[MAXN],f[MAXN];

long n;

long lowbit(long x)

{

    return x&-x;

}

long sum(long x)

{

    long ret=0;

    while(x>0)

    {

        ret+=c[x];

        x-=lowbit(x);

    }

    return ret;

}

void add(long x,long d)

{

    while(x<=n)

    {

        c[x]+=d;

        x+=lowbit(x);

    }

}

bool cmp(NODE x,NODE y)

{

    return  x.t<y.t;

}

int main(void)

{

    long i,pre,v;

    long long ans;

    scanf("%ld",&n);

    for(i=1; i<=n; i++)

    {

        scanf("%ld",&a[i].t);

        a[i].id=i;

    }

    sort(a+1,a+n+1,cmp);

    memset(c,0,sizeof(c));

    pre=-1;

    v=0;

    for(i=1; i<=n; i++)

    if(a[i].t!=pre)

    {

        pre=a[i].t;

        a[i].t=++v;

    }

    else

    a[i].t=v;

    ans=0;

    for(i=1;i<=n;i++)

    f[a[i].id]=a[i].t;

    for(i=n; i>=1; i--)

    {

        add(f[i],1);

        ans+=sum(f[i]-1);

    }

    printf("%I64d\n",ans);

    return 0;

}

你可能感兴趣的:(version)