树状数组求逆序对板子
逆序对本质是(一个数和在它前面且大于它的数的序偶)的集合
对于求逆序对的树状数组,我们将它视为一个桶
用于快速统计一个数前面比它小的有多少个
(因为树状数组能够快速求和)
由于已经知道它前面有多少个数了(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]);
}

浙公网安备 33010602011771号