meaning of the title
Sol
What is the space complexity of two-dimensional line tree
Why is the whole network space \ (n^2 \) and someone insisted that it is \ (nlog^2n \)
For this problem, because there are modification operations, we need to mark the outer line tree, and the form of the mark is to assign a value to an interval. So we need to open the segment tree for each tag to maintain the changed position
In addition, as we pull down from a line tree, we find the maximum value of the line tree of the subtree and upload it. Obviously, the complexity will explode, so we should consider the permanence of the mark
Specifically, when we write a line segment tree, if we mark an assignment mark on an interval, obviously its subtrees will be affected. And the maximum value of an interval will have an impact on its father, so directly open two arrays to record
And then, in the process of recursion, just deal with the tag
// luogu-judger-enable-o2 // luogu-judger-enable-o2 // luogu-judger-enable-o2 /* */ #include<bits/stdc++.h> #define LL long long using namespace std; const int MAXN = 2001, INF = 1e9 + 10; void chmin(int &a, int b) {a = (a < b ? a : b);} void chmax(int &a, int b) {a = (a > b ? a : b);} int sqr(int x) {return x * x;} inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, M, Q; struct InSeg { int rt[MAXN], ls[MAXN], rs[MAXN], mx[MAXN], tag[MAXN], tot; void update(int k) { mx[k] = max(mx[ls[k]], mx[rs[k]]); } void ps(int k, int v) { chmax(mx[k], v); chmax(tag[k], v); } void pushdown(int k) { if(!tag[k]) return ; if(!ls[k]) ls[k] = ++tot; if(!rs[k]) rs[k] = ++tot; ps(ls[k], tag[k]); ps(rs[k], tag[k]); tag[k] = 0; } void IntMem(int &k, int l, int r, int ll, int rr, int v) { if(!k) k = ++tot; if(ll <= l && r <= rr) {ps(k, v); return ;} pushdown(k); int mid = l + r >> 1; if(ll <= mid) IntMem(ls[k], l, mid, ll, rr, v); if(rr > mid) IntMem(rs[k], mid + 1, r, ll, rr, v); update(k); } int Query(int k, int l, int r, int ll, int rr) { if(!k) return 0; if(ll <= l && r <= rr) return mx[k]; pushdown(k); int mid = l + r >> 1, ans = 0; if(ll <= mid) chmax(ans, Query(ls[k], l, mid, ll, rr)); if(rr > mid) chmax(ans, Query(rs[k], mid + 1, r, ll, rr)); return ans; } }; int ls[MAXN], rs[MAXN], rtag[MAXN], rmx[MAXN], tot, root; InSeg tag[MAXN], mx[MAXN]; void IntMem(int &k, int l, int r, int a, int b, int ll, int rr, int v) { if(!k) k = ++tot; mx[k].IntMem(rmx[k], 1, M, ll, rr, v); if(a <= l && r <= b) { tag[k].IntMem(rtag[k], 1, M, ll, rr, v); return ; } int mid = l + r >> 1; if(a <= mid) IntMem(ls[k], l, mid, a, b, ll, rr, v); if(b > mid) IntMem(rs[k], mid + 1, r, a, b, ll, rr, v); } int Query(int k, int l, int r, int a, int b, int ll, int rr) { if(!k) return 0; int ans = tag[k].Query(rtag[k], 1, M, ll, rr); if(a <= l && r <= b) return max(ans, mx[k].Query(rmx[k], 1, M, ll, rr)); int mid = l + r >> 1; if(a <= mid) chmax(ans, Query(ls[k], l, mid, a, b, ll, rr)); if(b > mid) chmax(ans, Query(rs[k], mid + 1, r, a, b, ll, rr)); return ans; } signed main() { N = read(); M = read(); Q = read(); while(Q--) { int d = read(), s = read(), h = read(), x = read(), y = read(); //printf("**%d %d %d %d %d\n", x + 1, x + d, y + 1, y + s, h); IntMem(root, 1, N, x + 1, x + d, y + 1, y + s, Query(root, 1, N, x + 1, x + d, y + 1, y + s) + h); } printf("%d\n", Query(1, 1, N, 1, N, 1, M)); return 0; } /* 7 5 4 4 3 2 0 0 3 3 1 3 0 7 1 2 0 3 2 3 3 2 2 */