题意
让你解决一个装箱问题,给你两种算法,让你求用这两种算法解决问题得到的方案
解题思路
对于第一种方法,用线段树维护区间最大值,要注意需要先判断左边以保证找到最前面的。
对于d第二种方法,使用lower_bound直接模拟即可
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int a[N];
int n, c, T;
struct node {
int l, r;
int maxx;
int tag;
}t[N<<2];
void push_up(int u) {
t[u].maxx = max(t[u<<1].maxx, t[u<<1|1].maxx);
}
void push_down(int u) {
if (t[u].tag != 0) {
t[u<<1].tag = t[u].tag;
t[u<<1|1].tag = t[u].tag;
t[u<<1].maxx += t[u].tag;
t[u<<1|1].maxx += t[u].tag;
t[u].tag = 0;
}
}
void build(int l, int r, int u) {
t[u].l = l, t[u].r = r;
t[u].maxx = c;
t[u].tag = 0;
if (t[u].l == t[u].r) {
return;
}
int mid = (l + r) >> 1;
build(l, mid, u<<1);
build(mid+1, r, u<<1|1);
push_up(u);
}
void update(int pos, int u, int v) {
if (t[u].l == t[u].r) {
t[u].maxx += v;
t[u].tag += v;
return;
}
push_down(u);
int mid = (t[u].l + t[u].r) >> 1;
if (pos <= mid) update(pos, u<<1, v);
else update(pos, u<<1|1, v);
push_up(u);
}
int query(int val, int u) {
if (t[u].l == t[u].r) {
return t[u].l;
}
push_down(u);
if (val <= t[u<<1].maxx) return query(val, u<<1);
else return query(val, u<<1|1);
}
int main() {
scanf("%d", &T);
while (T--) {
scanf("%d %d", &n, &c);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
build(1, n, 1);
int Max_bot = 0;
for (int i = 1; i <= n; i++) {
int pos = query(a[i], 1);
Max_bot = max(Max_bot, pos);
update(pos, 1, -a[i]);
}
map<int, int> mp;
mp[c] = 1;
for (int i = 1; i <= n; i++) {
auto it = mp.lower_bound(a[i]);
if (it == mp.end()) {
mp[c-a[i]]++;
}
else {
mp[it->first - a[i]] ++;
mp[it->first]--;
if (mp[it->first] == 0) mp.erase(it);
}
}
int Max_bot_2 = 0;
for (auto x : mp) Max_bot_2 += x.second;
printf("%d %d\n", Max_bot, Max_bot_2);
}
}