C - Kaiten Sushi
把寿司都放到一个堆里,从前往后扫 \(A\) 数组,如果当前食客 \(A_i\) 小于等于堆顶,就取出堆顶,记录这份寿司被第 \(i\) 个人吃掉。复杂度 \(O(n\log m)\)。
D - Keep Distance
搜索回溯,但每一步从 \(10\) 枚举到 \(m\) 会超时,剪一下枝 for (int i = 10; res.back() + i <= m - 10 * (n - siz - 1); i++)
。
F - Falling Stars
把横线从下到上排序,开一棵线段树记录每个位置摞了多少层。要加入一条横线的时候,先查询对应区间 \([C_i,C_i+L_i-1]\) 的最小值(最高层数)\(r\),则该横线的层数就是 \(r-1\),区间赋值 \(r-1\) 即可。
#include <bits/stdc++.h>
using namespace std;
int main() {
cin.tie(0)->sync_with_stdio(0);
int H, W, n;
cin >> H >> W >> n;
struct Bar {
int R, C, L, id;
bool operator<(const Bar& o) const {
return R > o.R;
}
};
vector<Bar> bars(n);
for (int i = 0; i < n; i++) {
Bar& b = bars[i];
cin >> b.R >> b.C >> b.L;
b.id = i;
}
sort(bars.begin(), bars.end());
class SegmentTree {
struct Node;
using NodePtr = shared_ptr<Node>;
struct Node {
int l, r, val, tag;
NodePtr ls, rs;
Node(int l, int r, int val, int tag,
NodePtr ls = nullptr,
NodePtr rs = nullptr)
: l(l), r(r), val(val), tag(tag), ls(ls), rs(rs) {}
};
private:
NodePtr root;
void refresh(NodePtr p) {
p->val = min(p->ls->val, p->rs->val);
}
void build(NodePtr& p, int l, int r) {
p = make_shared<Node>(l, r, 0, 0);
if (l == r) return;
int mid = (l + r) >> 1;
build(p->ls, l, mid);
build(p->rs, mid + 1, r);
}
void applyFillTag(NodePtr p, int v) {
p->val = p->tag = v;
}
void pushDown(NodePtr p) {
if (!p->tag) return;
applyFillTag(p->ls, p->tag);
applyFillTag(p->rs, p->tag);
p->tag = 0;
}
void fillRange(NodePtr p, int l, int r, int val) {
if (l <= p->l && p->r <= r)
return applyFillTag(p, val), void(0);
pushDown(p);
int mid = (p->l + p->r) >> 1;
if (l <= mid) fillRange(p->ls, l, r, val);
if (r > mid) fillRange(p->rs, l, r, val);
refresh(p);
}
int queryMin(NodePtr p, int l, int r) {
if (l <= p->l && p->r <= r)
return p->val;
pushDown(p);
int mid = (p->l + p->r) >> 1;
int res = INT_MAX;
if (l <= mid) res = min(res, queryMin(p->ls, l, r));
if (r > mid) res = min(res, queryMin(p->rs, l, r));
return res;
}
public:
SegmentTree(int l, int r) { build(root, l, r); }
void fillRange(int l, int r, int val) { fillRange(root, l, r, val); }
int queryMin(int l, int r) { return queryMin(root, l, r); }
};
SegmentTree tr(1, W);
tr.fillRange(1, W, H + 1);
vector<int> ans(n);
for (auto& b : bars) {
ans[b.id] = tr.queryMin(b.C, b.C + b.L - 1) - 1;
tr.fillRange(b.C, b.C + b.L - 1, ans[b.id]);
}
for (int i = 0; i < n; i++) {
cout << ans[i] << '\n';
}
return 0;
}
标签:val,rs,int,题解,tag,ls,ABC382,NodePtr
From: https://www.cnblogs.com/th19/p/18592579