POI2006 TET-Tetris 3D
第一次写二维线段树
二维线段树模板题
感觉二维线段树很迷代码倒是挺好记
还得再理解理解
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
#define ls p << 1
#define rs p << 1 | 1
using namespace std;
LL read() {
LL k = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
k = k * 10 + c - 48, c = getchar();
return k * f;
}
int n, m, t;
struct zzz {
int maxn[901 << 2], tag[901 << 2];
void update(int nl, int nr, int k, int l = 1, int r = m, int p = 1) {
maxn[p] = max(maxn[p], k);
if(l >= nl && r <= nr) {
tag[p] = max(tag[p], k); return ;
}
int mid = (l+r) >> 1;
if(nl <= mid) update(nl, nr, k, l, mid, ls);
if(nr > mid) update(nl, nr, k, mid+1, r, rs);
}
int query(int nl, int nr, int l = 1, int r = m, int p = 1) {
if(l >= nl && r <= nr) return max(maxn[p], tag[p]);
int mid = (l+r) >> 1, ans = tag[p];
if(nl <= mid) ans = max(ans, query(nl, nr, l, mid, ls));
if(nr > mid) ans = max(ans, query(nl, nr, mid+1, r, rs));
return ans;
}
};
struct hhh {
zzz maxn[901 << 2], tag[901 << 2];
void update(int nl, int nr, int kl, int kr, int k, int l = 1, int r = n, int p = 1) {
maxn[p].update(kl, kr, k);
if(l >= nl && r <= nr) {
tag[p].update(kl, kr, k); return ;
}
int mid = (l+r) >> 1;
if(nl <= mid) update(nl, nr, kl, kr, k, l, mid, ls);
if(nr > mid) update(nl, nr, kl, kr, k, mid+1, r, rs);
}
int query(int nl, int nr, int kl, int kr, int l = 1, int r = n, int p = 1) {
if(l >= nl && r <= nr) return maxn[p].query(kl, kr);
int mid = (l+r) >> 1, ans = tag[p].query(kl, kr);
if(nl <= mid) ans = max(ans, query(nl, nr, kl, kr, l, mid, ls));
if(nr > mid) ans = max(ans, query(nl, nr, kl, kr, mid+1, r, rs));
return ans;
}
}tree;
int main() {
n = read(), m = read(), t = read();
while(t--) {
int d = read(), s = read(), h = read(), x = read()+1, y = read()+1;
h += tree.query(x, x+d-1, y, y+s-1);
tree.update(x, x+d-1, y, y+s-1, h);
}
cout << tree.query(1, n, 1, m);
return 0;
}