zoukankan      html  css  js  c++  java
  • 洛谷P4560 [IOI2014]Wall 砖墙

    题意

    传送门

    简化题意:

    给定长度为(n)的初始值都为(0)的序列,有(m)次操作,求(m)次操作过后的整个序列

    每次操作如下:

    (1.)对区间([l,r])中的所有元素与(h)(max)

    (2.)对区间([l,r])中的所有元素与(h)(min)

    分析

    线段树好题

    一道 区修 单查 可离线 的题目

    首先我们要明确这道题(2e6)的数据大概率就是要用线段树在(O(nlogn))时间范围内解决

    然后我们现在的问题就在于要维护哪些标记

    首先,我们最后要询问的值是(val),还是单点,所以我们可以知道这个维护的东西是什么都无所谓,只要能确定某个单点的值就行了

    然后看到题目这个肯定跟区间的最大值和最小值有关,那么我们干脆就维护(Max)(Min)标记吧~

    (Max)(Min)分别代表区间最大值和区间最小值

    那么我们考虑标记如何下传,就是(pushdown)函数的写法

    我们可以发现这样的一个事情(关于下传标记时的标记覆盖问题)

    就是如果我们当前这个点的两个标记为(Max1)(Min1),那么假设我们现在要从这个点的父亲结点下传一个(Min2)标记:

    [Max1=min{(Max1,Min2)}\ Min1=min{(Min1,Min2)} ]

    然后(Max2)标记也同理:

    [Max1=max{(Max1,Max2)}\ Min1=max{(Min1,Max2)} ]

    这样我们就解决了(pushdown)函数的问题啦~

    那么代码也不难得出,其他具体的细节也在代码里看吧

    代码

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;char ch=getchar();bool f=false;
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    const int N=2e6+5;
    int n,m,op;
    int maxn[N<<2],minn[N<<2];
    void pushdown(int x){
    	maxn[x<<1]=max(maxn[x<<1],maxn[x]);
    	minn[x<<1]=max(minn[x<<1],maxn[x]);
    	maxn[x<<1|1]=max(maxn[x<<1|1],maxn[x]);
    	minn[x<<1|1]=max(minn[x<<1|1],maxn[x]);
    	maxn[x<<1]=min(maxn[x<<1],minn[x]);
    	minn[x<<1]=min(minn[x<<1],minn[x]);
    	maxn[x<<1|1]=min(maxn[x<<1|1],minn[x]);
    	minn[x<<1|1]=min(minn[x<<1|1],minn[x]);
    	maxn[x]=0,minn[x]=0x3f3f3f3f;
    	return ;
    }
    void modify1(int x,int l,int r,int ql,int qr,int val){
    	if(ql<=l&&qr>=r){
    		maxn[x]=max(maxn[x],val);
    		minn[x]=max(minn[x],val);
    		return ;
    	}
    	pushdown(x);
    	int mid=(l+r)>>1;
    	if(ql<=mid) modify1(x<<1,l,mid,ql,qr,val);
    	if(qr>mid) modify1(x<<1|1,mid+1,r,ql,qr,val);
    	return ;
    }
    void modify2(int x,int l,int r,int ql,int qr,int val){
    	if(ql<=l&&qr>=r){
    		maxn[x]=min(maxn[x],val);
    		minn[x]=min(minn[x],val);
    		return ;
    	}
    	pushdown(x);
    	int mid=(l+r)>>1;
    	if(ql<=mid) modify2(x<<1,l,mid,ql,qr,val);
    	if(qr>mid) modify2(x<<1|1,mid+1,r,ql,qr,val);
    	return ;
    }
    int query(int x,int l,int r,int ql,int qr){
    	if(l==r) return maxn[x];
    	pushdown(x);
    	int mid=(l+r)>>1;
    	if(ql<=mid) return query(x<<1,l,mid,ql,qr);
    	else if(qr>mid) return query(x<<1|1,mid+1,r,ql,qr);
    	return 0;
    }
    int main(){
    	read(n),read(m);
    	for(int i=1;i<=(n<<2);i++) maxn[i]=0,minn[i]=0x3f3f3f3f;
    	while(m--){
    		read(op);
    		int l,r,h;
    		read(l),read(r),read(h);
    		l++,r++;
    		if(op==1) modify1(1,1,n,l,r,h);
    		else modify2(1,1,n,l,r,h);
    	}
    	for(int i=1;i<=n;i++) write(query(1,1,n,i,i)),putchar('
    ');
    	return 0;
    }
    
    
  • 相关阅读:
    vm 克隆一台新机器启动网卡报错:device eth0 does not seem to be present, delaying initialization
    DHCP server 冒充及DOS攻击处理方案
    linux、centos下查看系统版本、bios版本,内存信息等
    ubuntu 下当前网速查看
    ubuntu的文本界面修改字体大小
    mysql增加远程连接用户及查看数据库表结构
    数据库问题-复杂流量问题的排查
    python处理空格脚本
    winform水平滚动条联动panel
    winform自定义日期控件,要求可以手动输入日期DatePicker
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14126968.html
Copyright © 2011-2022 走看看