BZOJ4364:[IOI2014]Wall
阿新 • • 發佈:2019-01-06
淺談區間最值操作與歷史最值問題:https://www.cnblogs.com/AKMer/p/10225100.html
題目傳送門:https://lydsy.com/JudgeOnline/problem.php?id=4364
似乎可以不用吉司機線段樹的作法……因為只需要維護區間最大最小值,也只有區間取最大最小值操作,所以可以直接用普通的線段樹延遲標記解決這道問題。只要把最大值標記和最小值標記之間的關係處理得當即可。
時間複雜度:\(O((n+m)logn)\)
空間複雜度:\(O(n)\)
程式碼如下:
#include <cstdio> #include <algorithm> using namespace std; const int maxn=2e6+6,inf=1e9; int n,m; int read() { int x=0,f=1;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1; for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0'; return x*f; } struct segmemt_tree { int mx[maxn<<2],mn[maxn<<2]; int tagmx[maxn<<2],tagmn[maxn<<2]; void update(int p) { mx[p]=max(mx[p<<1],mx[p<<1|1]); mn[p]=min(mn[p<<1],mn[p<<1|1]); } void build(int p,int l,int r) { tagmx[p]=-inf,tagmn[p]=inf; if(l==r)return; int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); } void Max_tag(int p,int v) { mx[p]=max(mx[p],v),mn[p]=max(mn[p],v); tagmx[p]=max(tagmx[p],v);tagmn[p]=max(tagmn[p],v); } void Min_tag(int p,int v) { mx[p]=min(mx[p],v),mn[p]=min(mn[p],v); tagmx[p]=min(tagmx[p],v),tagmn[p]=min(tagmn[p],v); } void push_down(int p) { if(tagmx[p]!=-inf) { Max_tag(p<<1,tagmx[p]); Max_tag(p<<1|1,tagmx[p]); tagmx[p]=-inf; } if(tagmn[p]!=inf) { Min_tag(p<<1,tagmn[p]); Min_tag(p<<1|1,tagmn[p]); tagmn[p]=inf; } } void Max(int p,int l,int r,int L,int R,int v) { if(L<=l&&r<=R) { Max_tag(p,v); return; } int mid=(l+r)>>1;push_down(p); if(L<=mid)Max(p<<1,l,mid,L,R,v); if(R>mid)Max(p<<1|1,mid+1,r,L,R,v); update(p); } void Min(int p,int l,int r,int L,int R,int v) { if(L<=l&&r<=R) { Min_tag(p,v); return; } int mid=(l+r)>>1;push_down(p); if(L<=mid)Min(p<<1,l,mid,L,R,v); if(R>mid)Min(p<<1|1,mid+1,r,L,R,v); update(p); } void print(int p,int l,int r) { if(l==r) {printf("%d\n",mx[p]);return;} int mid=(l+r)>>1;push_down(p); print(p<<1,l,mid),print(p<<1|1,mid+1,r); } }T; int main() { n=read(),m=read();T.build(1,1,n); for(int i=1;i<=m;i++) { int opt=read(),l=read()+1,r=read()+1,v=read(); if(opt==1)T.Max(1,1,n,l,r,v); else T.Min(1,1,n,l,r,v); }T.print(1,1,n); return 0; }