树状数组 模板3 求逆序对(非离散化)

介绍离散化树状数组与普通树状数组的区别,普通树状数组用顺序下标放值,而离散化树状数组用要查询的数作下标。求逆序对时,在数字大小位置添加1更新树状数组,用当前位数减去前面比它小的数得到逆序数,值过大时需离散处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

离散化的树状数组:https://blog.youkuaiyun.com/A_Pathfinder/article/details/88042960

这里就提一下和普通树状数组的区别,这里是用要查询的数当作下标,而普通树状数组是直接顺序下标放值,也就是说区别在于
updata函数,普通的是updata(i,k);//这里的i就单纯是区间下标;而求逆序对的时候是updata(a[i],1)。我们每次都是在这个数字大小的位置上添加1,然后去更新树状数组,在计算逆序数的时候,只需要查看一下比这个数小或等于的数有多少个,然后现在的位数减去前面比它小的就是所得这一位的逆序数。所有如果要判断的值过大,就要离散处理了。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000000;
int c[maxn];
int n;
int lowbit(int x){
	return x&(-x);
}
void updata(int pos,int k){
	for(int i=pos;i<=n;i+=lowbit(i))
	c[i]+=k; 
}
int getsum(int x){
	int ans=0;
    for(int i=x;i;i-=lowbit(i)){
		ans+=c[i];
	}
	return ans;
}
int main(){
	int nx=0,a;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
	scanf("%d",&a);
	updata(a,1);
	nx+=(i-getsum(a));//用他在的位置减去比他小的个数,就是前面比他大的个数
	}
	cout<<nx;
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值