[2286. 以组为单位订音乐会的门票] 线段树

class BookMyShow {
    long[] sum ;
    long[] max;
    int n;
    int m;
    int last = -1;
    int ans = 0;

    public static void main(String[] args) {
        BookMyShow bookMyShow = new BookMyShow(5,9);
        bookMyShow.gather(10,1);
        bookMyShow.scatter(3,3);
        bookMyShow.gather(9,1);
        bookMyShow.gather(10,2);
        bookMyShow.gather(2,0);
    }

    public void build(int id,int l,int r){
        if(l == r){
            sum[id] = m;
            max[id] = m;
            return;
        }
        int mid = (l + r) /2;
        build(id+id,l,mid);
        build(id+id +1, mid+1,r);
        sum[id] = sum[id+id] + sum[id+id+1];
        max[id] = Math.max(max[id+id],max[id+id+1]);
        ans = 0;
    }

    /**
     * 找大于val的最大的最小坐标;
     * @return
     */
    public int queryMx(int id,int l,int r,int val){
        if(l == r){
            ans = (int) max[id];
            return l;
        }
        int mid = (l + r )/2;
        if(val<= max[id+id]){
            return queryMx(id+id,l,mid,val);
        }else{
            return queryMx(id+id+1,mid+1,r,val);
        }
    }

    /**
     * 更新【pos的位置为val
     */
    public void modify(int id,int l,int  r,int pos,int val){
        if( l == pos && r == pos){
            sum[id] = val;
            max[id] = val;
            return;
        }
        int mid = (l + r)/2;
        if( pos <= mid){
            modify(id+id,l,mid,pos,val);
        }else{
            modify(id+id+1,mid+1,r,pos,val);
        }
        sum[id] = sum[id+id] + sum[id+id+1];
        max[id] = Math.max(max[id+id],max[id+id+1]);
    }

    public BookMyShow(int n, int m) {
        sum = new long[4*n+1];
        max = new long[4*n+1];
        this.n  = n;
        this.m = m;
        build(1,0,n-1);
        this.last = -1;
    }

    public int[] gather(int k, int maxRow) {
        if(max[1] < k){
            return new int[]{};
        }
        int t = queryMx(1,0,n-1,k);
        if(t > maxRow){
            return new int[]{};
        }
        modify(1,0,n-1,t,ans - k);
        return new int[]{t,m - ans};
    }

    /**
     *  找到sum之和大于k的最小的位置
     */
    public int querySumx(int id,int l,int r,long k){
        if( l == r){
            ans = (int) (max[id] - k);
            return l;
        }
        int mid = (l + r )/2;
        if( k<= sum[id+id] ){
            return querySumx(id+id,l,mid,k);
        }else{
            return querySumx(id+id+1,mid+1,r,k- sum[id+id]);
        }
    }

    public boolean scatter(int k, int maxRow) {
        if( sum[1] < k){
            return false;
        }
        int t = querySumx(1,0,n-1,k);
        if( t > maxRow){
            return false;
        }
        for(int x=last+1;x<t;x++){
            modify(1,0,n-1,x,0);
        }
        last =Math.max(last,t-1);
        modify(1,0,n-1,t,ans);
        return true;
    }
}

/**
 * Your BookMyShow object will be instantiated and called as such:
 * BookMyShow obj = new BookMyShow(n, m);
 * int[] param_1 = obj.gather(k,maxRow);
 * boolean param_2 = obj.scatter(k,maxRow);
 */

 

posted @ 2022-05-30 19:04  fishcanfly  阅读(29)  评论(0)    收藏  举报
//雪花飘落效果