下推标记法,更新区间最值,并维护一个属性------区间是否平齐,更新时把所有区间一直分解成平齐区间在决定是否修改。
感觉跑上去很慢,但实际却已经足够快,原因可能是数据弱。
#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cctype>
//using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define max(a,b) ((a) > (b) ? (a) : (b))
const int maxn = 211;
const int M = 101111;
int MAX[M<<2],col[M<<2],flush[M<<2];
void build(int l,int r,int rt){
col[rt] = 0;
flush[rt] = true;
MAX[rt] = 0;
if(l==r) return ;
int m = (l+r)>>1;
build(lson);
build(rson);
}
int push_up(int rt){
flush[rt]=(flush[rt<<1]&&flush[rt<<1|1]&&MAX[rt<<1]==MAX[rt<<1|1]);
MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
}
int push_down(int rt){
if(col[rt]){
if(col[rt]>col[rt<<1]){
col[rt<<1] = col[rt];
MAX[rt<<1] = col[rt];
flush[rt<<1] = true;
}
if(col[rt]>col[rt<<1|1]){
col[rt<<1|1] = col[rt];
MAX[rt<<1|1] = col[rt];
flush[rt<<1|1] = true;
}
col[rt] = 0;
}
}
int ans = 0;
void update(int l,int r,int rt,int L,int R,int h){
if(L<=l&&r<=R&&flush[rt]){
if(MAX[rt]>h) return ;
col[rt] = h;
MAX[rt] = h;
ans+=r-l+1;
return ;
}
push_down(rt);
int m = (l+r)>>1;
if(L <= m) update(lson,L,R,h);
if(R > m) update(rson,L,R,h);
push_up(rt);
}
int main()
{
int x,y,z;
int lim = 100005;
int T,Q;
scanf("%d",&T);
while(T--){
scanf("%d",&Q);
ans = 0;
build(1,lim,1);
while(Q--){
scanf("%d %d %d",&x,&y,&z);
if(x==y) continue;
update(1,lim,1,x,y-1,z);
}
printf("%d\n",ans);
}
return 0;
}