统计对于每个i<j,求a[i]>a[j]的数量
在每一次更新(update)树状数组时,以元素的值作为树状数组的索引,更新的值为 +1,代表个数。
在每一次获取(query)逆序对数时,存在于树状数组中的元素的索引值都比当前元素的大(逆序遍历),
那么自然获取到的树状数组的值即为索引值比当前元素的大,且值比当前元素的小的个数。
从排列中的最后一个数开始遍历,每次在树状数组中查询有多少个数小于当前的数P[j]
(即用树状数组查询数组A目前P[j]−1个数的前缀和)并加入计数器,之后对树状数组执行修改数组A第P[j]个数值加1的操作。
#include<bits/stdc++.h>using namespace std;using ll=long long;
const int N=5e5+5;
int n,rng;
int a[N],org[N];
struct TreeArray{
private:ll bitree[N];
public:ll lowbit(int x){ return x&(-x);}void update(int pos,int val){for(;pos<=rng;pos+=lowbit(pos)) bitree[pos]+=val;//注意,下标为离散化后的值域}ll query(int pos){int res=0;for(;pos;pos-=lowbit(pos)) res+=bitree[pos];return res;}
};
TreeArray tree;int main(){cin.tie(nullptr)->sync_with_stdio(false);cin>>n;for(int i=1;i<=n;++i){cin>>a[i];org[i]=a[i];//保存原数据}sort(a+1,a+1+n);rng=unique(a+1,a+1+n)-a-1;//离散化的步骤,在部分题目中不是必需的ll ans=0;for(int i=n;i>=1;--i){int tmp=lower_bound(a+1,a+1+rng,org[i])-a;//获取排名ans+=tree.query(tmp-1);tree.update(tmp,1);}cout<<ans<<'\n';return 0;
}