UOJ #25. 【IOI2014】Wall 线段树
一眼吉司机线段树弱化版,但是这道题可以不用这么高级的数据结构.
直接用普通线段树,打一个 mx,mn 标记分别表示区间取 mn,max 然后 pushdown 的时候讨论一下大小关系即可.
code:
#include <bits/stdc++.h> #include "wall.h" #define lson x<<1 #define rson x<<1|1 #define N 2000006 #define setIO(s) freopen(s".in","r",stdin) using namespace std; const int inf=1000000000; int mn[N<<2],mx[N<<2],A[N]; void init() { for(int i=0;i<(N<<2);++i) mn[i]=0,mx[i]=inf; } void mark_min(int x,int v) { mn[x]=max(mn[x],v); mx[x]=max(mx[x],mn[x]); } void mark_max(int x,int v) { mx[x]=min(mx[x],v); mn[x]=min(mn[x],mx[x]); } void pushdown(int x) { mark_min(lson,mn[x]); mark_min(rson,mn[x]); mark_max(lson,mx[x]); mark_max(rson,mx[x]); mn[x]=0,mx[x]=inf; } void update(int l,int r,int x,int L,int R,int flag,int p) { if(l>=L&&r<=R) { if(flag==0) mark_min(x,p); else mark_max(x,p); return; } pushdown(x); int mid=(l+r)>>1; if(L<=mid) update(l,mid,lson,L,R,flag,p); if(R>mid) update(mid+1,r,rson,L,R,flag,p); } void query(int l,int r,int x,int *a) { if(l==r) { a[l-1]=mn[x]; return; } pushdown(x); int mid=(l+r)>>1; query(l,mid,lson,a),query(mid+1,r,rson,a); } void buildWall(int n, int k, int op[], int left[], int right[], int height[], int finalHeight[]) { init(); int m=k; for(int i=0;i<m;++i) { int l=left[i]+1,r=right[i]+1; if(op[i]==1) update(1,n,1,l,r,0,height[i]); if(op[i]==2) update(1,n,1,l,r,1,height[i]); } query(1,n,1,finalHeight); } /* int main() { // setIO("input"); init(); int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;++i) { int op,l,r,h; scanf("%d%d%d%d",&op,&l,&r,&h); ++l,++r; if(op==1) update(1,n,1,l,r,0,h); if(op==2) update(1,n,1,l,r,1,h); } query(1,n,1); return 0; } */