题意:求覆盖的长度,覆盖的要求是该线段最高
思路:线段树的区间修改,每次都插入一条线段,如果该线段覆盖的区间的最高值小于插入的线段,那么计算长度的时候遇到一条线段被分开会很麻烦,需要rp--
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; #define lson (rt<<1) #define rson (rt<<1|1) const int MAXN = 100010; const int MAX = 99999; struct segtree{ int l,r,Max,lazy; segtree(){} segtree(int _l, int _r){ l = _l,r = _r,Max = 0,lazy = 1; } int mid(){ return (l+r)>>1; } }t[MAXN<<2]; int n,lp[MAXN],rp[MAXN],h[MAXN]; void build(int rt, int l, int r){ t[rt] = segtree(l,r); if (l == r) return; int mid = t[rt].mid(); build(lson, l, mid); build(rson, mid+1, r); } void pushup(int rt){ if (t[rt].lazy == 0) return; t[lson].Max = t[rson].Max = t[rt].Max; t[rt].lazy = 0; } void update(int rt, int l, int r, int h){ if (t[rt].l == l && t[rt].r == r && t[rt].lazy){ if (h > t[rt].Max) t[rt].Max = h; return; } pushup(rt); int mid = t[rt].mid(); if (r <= mid) update(lson, l, r, h); else if (l > mid) update(rson, l, r, h); else { update(lson, l, mid, h); update(rson, mid+1, r, h); } } int query(int rt, int l, int r, int h){ if (t[rt].lazy){ if (t[rt].Max <= h){ update(rt, l, r, h); return r-l+1; } else return 0; } pushup(rt); int mid = t[rt].mid(); if (r <= mid) return query(lson, l, r, h); else if (l > mid) return query(rson, l, r, h); else { int a = query(lson, l, mid, h); int b = query(rson, mid+1, r, h); return a+b; } } int main(){ int t,n; scanf("%d", &t); while (scanf("%d", &n) != EOF && n){ int ans = 0; build(1, 1, MAX); for (int i = 0; i < n; i++){ scanf("%d%d%d", &lp[i], &rp[i], &h[i]); rp[i]--; int res = query(1, lp[i], rp[i], h[i]); ans += res; } printf("%d\n",ans); } return 0; }