b_lc_通过指令创建有序数组(树状数组+细节)

根据数组instructions中的元素创建一个有序数组nums,每一次插入操作的 代价 是以下两者的 较小值(n<=1e5):

  • nums中 严格小于 instructions[i] 的数字数目。
  • nums中 严格大于 instructions[i] 的数字数目。

思路:用树状数组维护a[i]维护≤i的元素的个数,lo很好求 ask(A[i]-1),hi的两种求法:

  1. ask(max(A))-ask(A[i])
  2. dup数组记录重复的元素的个数,hi=i-lo-dup[A[i]
const int N=1e5+5, mod=1e9+7;
class Solution {
public:
    int n,ans,a[N],dup[N];
    int lowbit(int x) {return x&-x;}
    void add(int x, int v) {
        for (; x<N; x+=lowbit(x)) a[x]+=v;
    }
    int ask(int x) {
        int c=0;
        for (; x; x-=lowbit(x)) c+=a[x], c%=mod;
        return c;
    }
    int createSortedArray(vector<int>& A) {
        n=A.size();
        for (int i=0; i<n; i++) {
            int lo=ask(A[i]-1), hi=ask(N-2)-ask(A[i]); //小于等于A[i]-1的数的个数
            ans=(ans+min(lo, hi))%mod; 
            add(A[i],1);
        }
        return ans;
    }
};
posted @ 2020-11-08 15:32  童年の波鞋  阅读(80)  评论(0编辑  收藏  举报