树状数组+离散化——求大范围,大数数组的逆序数

来源:互联网 发布:java免费培训 编辑:程序博客网 时间:2024/05/16 04:49
  • 模板转自网络(侵删)
#include <iostream>#include <string.h>#include <algorithm>#include <stdio.h>using namespace std;const int N = 500005;struct Node{    int v,order;//v为数字原来的值,order为数字原来的序号};int n;int c[N];int aa[N];    //离散化后的数组Node a[N];    //树状数组int Lowbit(int x){    return x & (-x);}void Update(int t,int val){    for(int i=t; i<=n; i+=Lowbit(i))    {        c[i] += val;    }}int getSum(int x){    int ans=0;    for(int i=x; i>0; i-=Lowbit(i))    ans += c[i];    return ans;}bool cmp(Node a,Node b){    return a.v<b.v;}int main(){    while(~scanf("%d",&n),n)    {        //离散化        for(int i=1; i<=n; i++)        {            scanf("%d",&a[i].v);            a[i].order=i;        }        sort(a+1,a+1+n,cmp);        for(int i=1; i<=n; i++)            aa[a[i].order]=i; //离散化每一个数字        //树状数组求逆序数——每一个数前面比它大的数的总和。        memset(c,0,sizeof(c));        long long ans=0;        for(int i=1; i<=n; i++)        {            Update(aa[i],1);            cout << i - getSum(aa[i]) << endl; //a[i]的逆序数            ans+=i-getSum(aa[i]);        }        printf("%I64d\n",ans); //总的逆序数    }    return 0;}
0 0
原创粉丝点击