AcWing 248. 窗内的星星(线段树 -- 扫描线)
作者:互联网
思路:
对于给定的点(星星)我们将他作为矩形的左下角
构造两条线段 seg左(x,y,y+h-1,c) seg右(x+w-1,y,y+h-1,-c)
然后线段树维护最大值
#include<bits/stdc++.h>
#include <unordered_map>
using namespace std;
template<class...Args>
void debug(Args... args) {//Parameter pack
auto tmp = { (cout << args << ' ', 0)... };
cout << "\n";
}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>pll;
typedef pair<int, int>pii;
const ll N = 2e5 + 5;
const ll INF = 0x7fffffff;
const ll MOD = 998244353;
struct segment {
ll key, l, r;//记录每一条线
ll k;//每一条线的权值(+1,-1)
bool operator < (const segment& t) const {
if (key == t.key)return k > t.k;
return key < t.key;
}
}seg[N << 1];
vector<ll> ys;//存储所有的y,用于离散化
ll get_pos(ll num) {
return lower_bound(ys.begin(), ys.end(), num) - ys.begin() + 1;
}
struct Tree {
struct node {
ll l, r;
ll maxv;//维护的是再w*h范围内的最大数
ll add;//加法懒标记
}tree[N << 2];
void push_up(int root) {
tree[root].maxv = max(tree[root << 1].maxv, tree[root << 1 | 1].maxv);
}
void build(int root, ll l, ll r) {
if(l==r)tree[root] = { l, r, 0, 0 };
else {
tree[root] = { l,r };
ll mid = l + r >> 1;
build(root << 1, l, mid);
build(root << 1 | 1, mid + 1, r);
}
}
void push_down(int root) {
if (tree[root].add) {
tree[root << 1].add += tree[root].add;
tree[root << 1 | 1].add += tree[root].add;
tree[root << 1].maxv += tree[root].add;
tree[root << 1 | 1].maxv += tree[root].add;
tree[root].add = 0;
}
}
void modify(int root, ll l, ll r, ll num) {
if (l <= tree[root].l && tree[root].r <= r) {//节点包含在修改区间内部则直接修改
tree[root].add += num;
tree[root].maxv += num;
}
else {
push_down(root);
int mid = tree[root].l + tree[root].r >> 1;
if (l <= mid)modify(root << 1, l, r, num);
if (r > mid)modify(root << 1 | 1, l, r, num);
push_up(root);
}
}
}tr;
int main() {
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int n, w, h;
while (cin >> n >> w >> h) {
int pos = 0;
for (int i = 0; i < n; i++) {
ll x, y, c;
cin >> x >> y >> c;
ys.push_back(y);
ys.push_back(y + h - 1);
seg[pos++] = { x,y,y + h - 1,c };
seg[pos++] = { x + w - 1,y,y + h - 1,-c };
}
sort(ys.begin(), ys.end());
ys.erase(unique(ys.begin(), ys.end()), ys.end());
ll ans = -1;
tr.build(1, 1, ys.size());
sort(seg, seg + 2 * n);
for (int i = 0; i < 2 * n; i++) {
ans = max(ans, tr.tree[1].maxv);
ll l = get_pos(seg[i].l);
ll r = get_pos(seg[i].r);
tr.modify(1, l, r, seg[i].k);
}
cout << ans << "\n";
}
return 0;
}
标签:窗内,const,key,--,ll,pos,seg,扫描线,ys 来源: https://blog.csdn.net/qq_45748404/article/details/121665759