• BZOJ4364:[IOI2014]Wall


    浅谈区间最值操作与历史最值问题: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
    ",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;
    }
    
  • 相关阅读:
    线程练习-网络买票
    永久储存信息(已完善)
    Linux命令
    oracle(3)
    小结
    java开发中中文编码问题
    double保留两位小数
    oracle(2)
    javadate相关
    分布式
  • 原文地址:https://www.cnblogs.com/AKMer/p/10227150.html
Copyright © 2020-2023  润新知