線段樹--luoguP4560 [IOI2014]Wall 磚牆
阿新 • • 發佈:2018-11-26
傳送門
很巧啊只需要維護上界和下界就好了
一開始以為要維護四個,其實只用維護兩個就好了,如果到了
的時候修改一下序列上的值就行。
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 2000005
#define ls cur<<1
#define rs cur<<1|1
using namespace std;
inline int rd(){
int x=0,f=1;char c=' ';
while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
inline int min(int x,int y){return x<y? x:y;}
inline int max(int x,int y){return x>y?x:y;}
int n,m,mn[N<<2],mx[N<<2],ans[N];
inline void pushdown(int cur,int l,int r){
if(l==r){
if(mn[cur]!=-1) ans[l]=min(ans[l],mn[cur]);
if(mx[cur]!=-1) ans[l]=max(ans[l],mx[cur]);
return;
}
if(mn[cur]!=-1){
if(mn[ls]!=-1) mn[ls] =min(mn[ls],mn[cur]);
else mn[ls]=mn[cur];
mx[ls]=min(mx[ls],mn[cur]);
if(mn[rs]!=-1) mn[rs]=min(mn[rs],mn[cur]);
else mn[rs]=mn[cur];
mx[rs]=min(mx[rs],mn[cur]);
mn[cur]=-1;
}
if(mx[cur]!=-1){
mx[ls]=max(mx[ls],mx[cur]); mx[rs]=max(mx[rs],mx[cur]);
if(mn[ls]!=-1) mn[ls]=max(mn[ls],mx[cur]);
if(mn[rs]!=-1) mn[rs]=max(mn[rs],mx[cur]);
mx[cur]=-1;
}
}
void update(int cur,int L,int R,int ql,int qr,int tp,int h){
if(L<=ql && qr<=R){
if(tp==1){
mx[cur]=max(mx[cur],h);
if(mn[cur]!=-1) mn[cur]=max(mn[cur],h);
}
else{
if(mn[cur]==-1) mn[cur]=h;
else mn[cur]=min(mn[cur],h);
if(mx[cur]!=-1) mx[cur]=min(mx[cur],h);
}
if(ql==qr){
if(mn[cur]!=-1) ans[ql]=min(ans[ql],mn[cur]);
if(mx[cur]!=-1) ans[ql]=max(ans[ql],mx[cur]);
} return;
}
int mid=(ql+qr)>>1; pushdown(cur,ql,qr);
if(L<=mid) update(ls,L,R,ql,mid,tp,h);
if(mid<R) update(rs,L,R,mid+1,qr,tp,h);
}
void query(int cur,int ql,int qr){
pushdown(cur,ql,qr);
if(ql==qr) {printf("%d\n",ans[ql]);return;}
int mid=(ql+qr)>>1;
query(ls,ql,mid); query(rs,mid+1,qr);
}
int main(){
n=rd(); m=rd(); memset(mn,-1,sizeof mn); memset(mx,-1,sizeof mx);
int t,l,r,h;
while(m--){
t=rd(); l=rd(); r=rd(); h=rd(); ++l,++r;
update(1,l,r,1,n,t,h);
}
query(1,1,n);
return 0;
}