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;
}
原文地址:https://www.cnblogs.com/zjbztianya/p/3026382.html