题意:求覆盖的长度,覆盖的要求是该线段最高
思路:线段树的区间修改,每次都插入一条线段,如果该线段覆盖的区间的最高值小于插入的线段,那么计算长度的时候遇到一条线段被分开会很麻烦,需要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;
}