本来以为有什么高深的做法.. 试了一发暴力剪枝就过了..
维护区间最大最小值即可
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define N 0x3f3f3f3f
struct node1
{
int l;
int r;
int h;
};
struct node2
{
int l;
int r;
int minn;
int maxx;
int laz;
};
node1 seg[100010];
node2 tree[400010];
int n;
void pushup(int cur)
{
tree[cur].minn=min(tree[2*cur].minn,tree[2*cur+1].minn);
tree[cur].maxx=max(tree[2*cur].maxx,tree[2*cur+1].maxx);
}
void pushdown(int cur)
{
if(tree[cur].laz!=0)
{
tree[2*cur].minn=tree[cur].laz;
tree[2*cur].maxx=tree[cur].laz;
tree[2*cur].laz=tree[cur].laz;
tree[2*cur+1].minn=tree[cur].laz;
tree[2*cur+1].maxx=tree[cur].laz;
tree[2*cur+1].laz=tree[cur].laz;
tree[cur].laz=0;
}
}
void build(int l,int r,int cur)
{
int m;
tree[cur].l=l;
tree[cur].r=r;
tree[cur].minn=0;
tree[cur].maxx=0;
tree[cur].laz=0;
if(l+1==r) return;
m=(l+r)/2;
build(l,m,2*cur);
build(m,r,2*cur+1);
}
ll solve(int pl,int pr,int h,int cur)
{
ll res,tmp;
if(tree[cur].minn>h) return 0;
if(pl<=tree[cur].l&&tree[cur].r<=pr&&tree[cur].maxx<=h)
{
tmp=tree[cur].r-tree[cur].l;
tree[cur].minn=h;
tree[cur].maxx=h;
tree[cur].laz=h;
return tmp;
}
if(tree[cur].l+1==tree[cur].r) return 0;
pushdown(cur);
res=0;
if(pl<tree[2*cur].r) res+=solve(pl,pr,h,2*cur);
if(pr>tree[2*cur+1].l) res+=solve(pl,pr,h,2*cur+1);
pushup(cur);
return res;
}
int main()
{
ll ans;
int t,i;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
build(1,100000,1);
ans=0;
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&seg[i].l,&seg[i].r,&seg[i].h);
ans+=solve(seg[i].l,seg[i].r,seg[i].h,1);
//printf("*%lld*\n",ans);
}
printf("%lld\n",ans);
}
scanf("%d",&t);
return 0;
}