[2019杭电多校第三场][hdu6609]Find the answer(线段树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6609

大致题意是求出每个位置i最小需要将几个位置j变为0(j<i),使得$\sum_{j=1}^{i}a[j]<=m$

可以将题意换一下,删除最少的个数=i-1-保留最多的个数。

则建权值线段树,同时维护个数与权值。题目转化为用最多的权值线段树中的数凑出m-a[i]这个数。

所以就从小到大取数即可。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<string>
 5 #include<cmath>
 6 #include<vector>
 7 #define lson l, mid, i<<1
 8 #define rson  mid + 1, r, i<<1|1
 9 using namespace std;
10 typedef long long ll;
11 const int maxn = 2e5 + 10;
12 ll val[maxn * 20];
13 int num[maxn * 20];
14 int a[maxn], b[maxn];
15 void up(int i) {
16     val[i] = val[i << 1] + val[i << 1 | 1];
17     num[i] = num[i << 1] + num[i << 1 | 1];
18 }
19 void build(int l, int r, int i) {
20     val[i] = num[i] = 0;
21     if (l == r)
22         return;
23     int mid = l + r >> 1;
24     build(lson);
25     build(rson);
26 }
27 int query(int pos, int l, int r, int i) {
28     if (val[i] <= pos)
29         return num[i];
30     if (l == r)
31         return min(num[i], pos / b[l]);//比较该数的个数和需要多少个数
32     int mid = l + r >> 1;
33     if (val[i << 1] >= pos)
34         return query(pos, lson);
35     else
36         return num[i << 1] + query(pos - val[i << 1], rson);
37 }
38 void update(int pos, int l, int r, int i) {
39     if (l == r) {
40         val[i] += b[pos];
41         num[i]++;
42         return;
43     }
44     int mid = l + r >> 1;
45     if (pos <= mid)update(pos, lson);
46     else update(pos, rson);
47     up(i);
48 }
49 int main() {
50     int t;
51     scanf("%d", &t);
52     while (t--) {
53         int n, m;
54         scanf("%d%d", &n, &m);
55         for (int i = 1; i <= n; i++)
56             scanf("%d", &a[i]), b[i] = a[i];
57         sort(b + 1, b + 1 + n);
58         int k = unique(b + 1, b + 1 + n) - b - 1;
59         build(1, k, 1);
60         for (int i = 1; i <= n; i++) {
61             if (i == 1)
62                 printf("0 ");
63             else
64                 printf("%d%c", i - 1 - query(m - a[i], 1, k, 1), i == n ? '\n' : ' ');
65             int pos = lower_bound(b + 1, b + 1 + k, a[i]) - b;
66             update(pos, 1, k, 1);
67         }
68     }
69 }

 

posted @ 2019-08-12 20:18  祈梦生  阅读(224)  评论(3编辑  收藏  举报