树状数组求逆序对板子

逆序对本质是(一个数和在它前面且大于它的数的序偶)的集合

对于求逆序对的树状数组,我们将它视为一个桶

用于快速统计一个数前面比它小的有多少个

(因为树状数组能够快速求和)

由于已经知道它前面有多少个数了(i-1个)

那么(前面数的总数-前面比它小的数)=前面比它大的数 = 该元素为第一关键字的逆序对个数

即遍历->树状数组操作->求逆序对的和

流程:

从1~n遍历需要求逆序对的数组

每遍历到一个元素a[i]便把它加入到树状数组中

求桶中1~a[i]元素的个数,由于循环先加入了a[i],那么前面比它小的数即为:a[i]-1

所以res=(i-1)-(a[i]-1)=i-a[i]

将res从1~n累加即为答案

另外桶的大小为数组元素最大值,所以有时候元素过大时需要进行离散化处理

int mn;
int lowbit(int x){
  return x&-x;
}
int t[maxn];//树状数组
void add(int x){
    while(x<=mn){
      t[x]++;
      x+=lowbit(x);
    }
}
int query(int x){
  int res=0;
  while(x){
    res+=t[x];
    x-=lowbit(x);
  }
  return res;
}
    mn=n;
   for(int i=1;i<=n;i++){
      add(res[i]);
      ans+=i-query(res[i]);
    }
posted @ 2025-05-01 17:42  Marinaco  阅读(43)  评论(0)    收藏  举报
//雪花飘落效果