Find the answer

2019 Multi-University Training Contest 3

Topic Address: http://acm.hdu.edu.cn/showproblem.php?pid=6609

Question is intended: to a sequence, for the i-th element, place the removed before the i-th and the previous number k of the i-th re summed together, removing the remaining, for each i and k the maximum requirements and does not exceed the number of digits m, i.e., removal of the remaining digits and add up to a minimum of less than or equal m, the number of digital output before it needs to be removed for each i, and since the large range of data needs to be discretized

Ideas: + discrete segment tree

For each i, i-1 which element into the position in front of the discretized segment tree and the number of intervals and a maintenance interval for each interval less than the sum of the number of direct section ma [i] of included in the answer, continue to look for is greater than the downward final tally answer, with i-1- answer is to remove the number, pay attention to the output format, with no spaces will not know the final number of PE why later. . . . .

 

// 
// the Created by Mile ON 2019/7/29.
 // 
// HDU multi-T7 school Day3 2019
 // discrete segment tree +
 // output formats: behind each number has a space, a space after each line of output 

#include <bits / STDC ++ H.> #define LID ID <<. 1
 #define RID ID. 1 << |. 1
 the using namespace STD; 
typedef Long Long LL;
 const int MAXN = 200005 ; struct the Num {
     int CNT, Val, ID; 
}; struct the Node {
     int L, R & lt, ID, COUNT; 
    LL SUM; 
}; BOOL

   





 cmp1(Num a, Num b) {
    return a.val == b.val ? a.id < b.id : a.val < b.val;
}

bool cmp2(Num a, Num b) {
    return a.id < b.id;
}

struct SegmentTree {
    ll n, m;
    Num num[maxn];
    Node tr[maxn<<2];

    void init(int n, int m) {
        this->n = n, this->m = m;
        for(int i = 1; i <= n; i++) {
            scanf("%d", &num[i].val);
            num[i].id = i;
        }
        sort(num+1, num+n+1, cmp1);
        for(int i = 1; i <= n; i++) num[i].cnt = i;
        sort(num+1, num+n+1, cmp2);
        build(1, 1, n);
    }

    void build(int id, int l, int r) {
        tr[id].l = l, tr[id].r = r;
        tr[id].sum = tr[id].count = 0;
        if(tr[id].l == tr[id].r) {
            return ;
        }
        int mid = (l+r)>>1;
        build(lid, l, mid);
        build(rid, mid+1, r);
        tr[id].sum = tr[lid].sum + tr[rid].sum;
    }

    void update(int id, int pos, int cnt) {
        if(tr[id].l == tr[id].r && tr[id].l == pos) {
            tr[id].sum = num[cnt].val; tr[id].count = 1;
            return ;
        }
        int mid = (tr[id].l + tr[id].r)>>1;
        if(pos <= mid) update(lid, pos, cnt);
        else update(rid, pos, cnt);
        tr[id].sum = tr[lid].sum+tr[rid].sum;
        tr[id].count = tr[lid].count+tr[rid].count;
    }

    int query(int id, ll sum) {
        if(tr[id].sum <= sum) return tr[id].count;
        if(tr[id].l == tr[id].r) return tr[id].sum <= sum;
        if(tr[lid].sum >= sum) return query(lid, sum);
        else return tr[lid].count+query(rid, sum-tr[lid].sum);
    }

    void solve() {
        for(int i = 1; i <= n; i++) {
            printf("%d ",i-1-query(1, m-num[i].val));
            update(1,num[i].cnt, num[i].id);
        }
        puts("");
    }
};

SegmentTree tree;


int main()
{
    int Q;
    scanf("%d", &Q);
    while(Q--) {
        ll n, m;
        scanf("%lld%lld", &n, &m);
        tree.init(n, m);
        tree.solve();
    }
    return 0;
}
View Code

 

  

Guess you like

Origin www.cnblogs.com/mile-star/p/11267416.html