其他分享
首页 > 其他分享> > 【求助帖】| 树状数组求逆序对

【求助帖】| 树状数组求逆序对

作者:互联网

在这里插入图片描述

#include <bits/stdc++.h>
#define read(x) scanf("%d",&x)
#define lowbit(x) ((x)&(-x))
using namespace std;

typedef long long ll;
const int N=1e5+10;
struct node {
    int h,idx;
    bool operator < (const node  &b) const {
        if (h!=b.h) return h<b.h; //身高升序排列,求下标的逆序对
        else return idx<b.idx;
    }
}a[N];
int tr[N],w[N],n;//w数组存储每个位置的数的逆序对的个数

void update(int x,int c) {
  for (int i=x;i<=n;i+=lowbit(i)) tr[i]+=c;
}

int query(int x) {
  int res=0;
  for (int i=x;i>=1;i-=lowbit(i)) res+=tr[i];
  return res;
}

ll getSum(int n) {
  return (ll)n*(n+1)/2;
}

int main()
{
    read(n);
    int h;
    for (int i=1;i<=n;i++) read(h),a[i]={h,i};
    
    //排序,
    sort(a+1,a+n+1);     
   //去重              
    for (int i=2;i<=n;i++) 
      if (a[i].h==a[i-1].h) a[i].idx=a[i-1].idx;
      
    //a[i]主动和谁换?求左边比a[i]大的
    for (int i=1;i<=n;i++) {
        update(a[i].idx,1);
        w[i]=i-query(a[i].idx);  
    }
    
    //a[i]被谁换?求右边比a[i]小的
    memset(tr,0,sizeof tr);
    for (int i=n;i>=1;i--) {
        update(a[i].idx,1);
        w[i]+=query(a[i].idx-1);
    }
    
    ll res=0;
    for (int i=1;i<=n;i++) res+=getSum(w[i]);
    printf("%lld",res);
    
    return 0;
}

但只能过两组数据,第三组数据就错了,不知道错哪了。哪天再回来看吧。

输入数据。

100
42 701 893 20 333 520 919 446 482 203 126 707 527 814 528 598 369 165 449 3 377 539 301 638 912 970 810 
102 149 983 713 410 472 89 382 785 142 824 73 141 199 825 317 679 219 597 548 67 343 467 566 580 924 337 
859 939 482 618 8 746 598 926 124 753 230 271 132 308 881 171 727 294 49 921 375 3 780 504 389 251 117
609 359 720 487 70 632 632 355 617 719 589 482 771 118 7 655 422 63 757

出错区间:

52
482 203 126 707 527 814 528 598 369 165 449 3 377 539 301 638 912 970 810 102 
149 983 713 410 472 89 382 785 142 824 73 141 199 825 317 679 219 597 548 67 
343 467 566 580 924 337 859 939 482 618 8 746 

标签:const,idx,树状,int,res,ll,求助,482,逆序
来源: https://blog.csdn.net/HangHug_L/article/details/115065568