#include <bits/stdc++.h> using namespace std; struct SGTree { int le, ri; int la; int mx; }t[40005]; struct Buildings { int l, r; int h; bool operator <(const Buildings A) const { return h < A.h; } }b[10005]; int a[10005]; void BuildT(int id, int l, int r)//建一个空树 { t[id].le = l; t[id].ri = r; t[id].la = 0;//lazy值为0 if (t[id].le == t[id].ri) { t[id].mx = 0; //max默认为0,建的是空树 return; } int mid = (l + r) / 2; BuildT(id * 2, l, mid); BuildT(id * 2 + 1, mid + 1, r); } void Push(int id)//la标记下放 { if (t[id].la) { t[id * 2].la = t[id].la;//lazy值迭代左子叶 t[id * 2 + 1].la = t[id].la; //迭代右子叶 t[id * 2].mx = max(t[id * 2].mx, t[id * 2].la); /* lazy值此处指更新后的值,无需再进行更改,然而 为什么lazy值推到左右子叶后仍然能正常使用?---我看了,真的可以,因为change传入参数c固定*/ t[id * 2 + 1].mx = max(t[id * 2 + 1].mx, t[id * 2 + 1].la); t[id].la = 0; } } void Change(int id, int l, int r, int c)//修改,注意细节 { if (t[id].le == l && t[id].ri == r) { t[id].mx = max(t[id].mx, c); t[id].la = c; //c是贯穿的常量,大概是把某个区间全数修改为int c,这就是模板 return; } Push(id);//push向下推id到他的子叶,以保证子叶的值被更新,这样此id的值在上推时完全安全 if (r <= t[id * 2].ri) { Change(id * 2, l, r, c); //二分递归查找 } else if (l >= t[id * 2 + 1].le) { Change(id * 2 + 1, l, r, c); } else { Change(id * 2, l, t[id * 2].ri, c); Change(id * 2 + 1, t[id * 2 + 1].le, r, c); } t[id].mx = max(t[id * 2].mx, t[id * 2 + 1].mx); } int Query(int id, int l, int r)//查询 { if (t[id].le == l && t[id].ri == r) { return t[id].mx; } Push(id); if (r <= t[id * 2].ri) { return Query(id * 2, l, r); } else if (l >= t[id * 2 + 1].le) { return Query(id * 2 + 1, l, r); } else { return max(Query(id * 2, l, t[id * 2].ri), Query(id * 2 + 1, t[id * 2 + 1].le, r)); } } int main() { BuildT(1, 1, 10000); int l, h, r; int cnt = 1; while (cin >> b[cnt].l >> b[cnt].h >> b[cnt].r) { if (b[cnt].l == 0 && b[cnt].r == 0 && b[cnt].h == 0) /*效率极差*/ { break; } cnt++; } sort(b + 1, b + cnt);//将高度排序,不然会错,我也不知道为什么 for (int i = 1; i < cnt; ++i) { Change(1, b[i].l, b[i].r - 1, b[i].h); //只是维护线段树的操作而已。 //你们省选选手都是些神经病,打个模拟还要线段树 } for (int i = 1; i <= 10000; ++i) { a[i] = Query(1, i, i);//数据结构,到时候在查,这样的效率能高吗? printf("%d ", a[i]); } for (int i = 1; i <= 10000; ++i) { if (a[i] != a[i - 1]) { printf("%d %d ", i, a[i]);//按照要求输出 } } return 0; }
我交了一下,是WA的。甚至还会掉ACC
原文:https://www.cnblogs.com/asanagiyantia/p/11585572.html