LC.315. 计算右侧小于当前元素的个数

传送门

思路:离散化权值树状数组。

显然因为可能存在负数,所以先离散化一波,然后从右到左遍历,将询问值储存起来,然后更新即可。

#define lowbit(x) x&(-x)
class Solution {
public:
    int tr[1000005],b[1000005];
    void update(int x,int k){
	while(x<=2e5){
		tr[x]+=k;
		x+=lowbit(x);
	 }
    }
    int query(int x){
	int ans=0;
	while(x){
		ans+=tr[x];
		x-=lowbit(x);
	}
	return ans;
    }
    vector<int> countSmaller(vector<int>& a) {
          int n=a.size();
          if(!n) return {};
          for(int i=1;i<=n;i++) b[i]=a[i-1];
          sort(b+1,b+1+n);
          int tot=unique(b+1,b+n+1)-b-1;
          for(int i=1;i<=n;i++) a[i-1]=lower_bound(b+1,b+1+n,a[i-1])-b;
          vector<int>ans;
          for(int i=n-1;i>=0;i--){
              int  cnt=query(a[i]-1);
              ans.push_back(cnt);
              update(a[i],1);
          }
          reverse(ans.begin(),ans.end());
          return ans;
    }
};