zoukankan      html  css  js  c++  java
  • 「雅礼集训 2018 Day7」A

    题意:「雅礼集训 2018 Day7」A

    题解:
    线段树处理。
    考虑只有一种与的操作。显然当一个区间的或和与上将要与的数还是原数时就没必要递归计算了,剪枝剪掉。当一段区间与和与上将要与的数等于这段区间或和与上将要与的数时,更新后这段区间的最小值位置还是更新前的位置。由于一次操作至少将数的一个二进制改变,所以最多改变 (log {INT_{MAX}}) 次,时间复杂度(O(n imes log {INT_{MAX}} imes log {n}))
    当存在两个修改操作时同样操作即可。

    代码:

    #include<bits/stdc++.h>
    #define re register
    using namespace std;
    const int N=500010,MX=2147483647;
    int n,m,a[N];
    struct P { int v,Or,And; };P t[N<<2];
    int lz_or[N<<2],lz_and[N<<2];
    
    template <typename T> inline void read(T &x) {
    	x=0;re char c=getchar();while(c<'0'||c>'9')	c=getchar();
    	while(c>='0'&&c<='9')	x=x*10+(c^48),c=getchar();
    }
    inline int Min(const int &x,const int &y) { return x<y?	x:y; }
    P pushup(P ls,P rs) {
    	P tt; tt.Or=ls.Or|rs.Or,tt.And=ls.And&rs.And;
    	tt.v=Min(ls.v,rs.v); return tt;
    }
    void push_or(int u,int w) {
    	lz_or[u]|=w,lz_and[u]|=w,t[u].v|=w,t[u].Or|=w,t[u].And|=w;
    }
    void push_and(int u,int w) {
    	lz_or[u]&=w,lz_and[u]&=w,t[u].v&=w,t[u].Or&=w,t[u].And&=w;
    }
    void pushdown(int u) {
    	if(lz_or[u]) {
    		push_or(u*2,lz_or[u]),push_or(u*2+1,lz_or[u]);
    		lz_or[u]=0;
    	}
    	if(lz_and[u]!=MX) {
    		push_and(u*2,lz_and[u]),push_and(u*2+1,lz_and[u]);
    		lz_and[u]=MX;
    	}
    }
    void build(int u,int l,int r) {
    	lz_or[u]=0,lz_and[u]=MX;
    	if(l>=r) { t[u].Or=t[u].And=t[u].v=a[l];return ; }
    	int mid=(l+r)>>1; build(u*2,l,mid),build(u*2+1,mid+1,r);
    	t[u]=pushup(t[u*2],t[u*2+1]);
    }
    void mdy_and(int u,int l,int r,int L,int R,int w) {
    	if((t[u].Or&w)==t[u].Or)	return ;
    	if(l==L&&r==R&&(t[u].And&w)==(t[u].Or&w))
    		{ push_and(u,w);return ; }
    	int mid=(l+r)>>1; pushdown(u);
    	if(R<=mid)	mdy_and(u*2,l,mid,L,R,w);
    	else if(L>mid)	mdy_and(u*2+1,mid+1,r,L,R,w);
    	else	mdy_and(u*2,l,mid,L,mid,w),mdy_and(u*2+1,mid+1,r,mid+1,R,w);
    	t[u]=pushup(t[u*2],t[u*2+1]);
    }
    void mdy_or(int u,int l,int r,int L,int R,int w) {
    	if((t[u].And|w)==t[u].And)	return ;
    	if(l==L&&r==R&&(t[u].And|w)==(t[u].Or|w))
    		{ push_or(u,w);return ; }
    	int mid=(l+r)>>1; pushdown(u);
    	if(R<=mid)	mdy_or(u*2,l,mid,L,R,w);
    	else if(L>mid)	mdy_or(u*2+1,mid+1,r,L,R,w);
    	else	mdy_or(u*2,l,mid,L,mid,w),mdy_or(u*2+1,mid+1,r,mid+1,R,w);
    	t[u]=pushup(t[u*2],t[u*2+1]);
    }
    int qry(int u,int l,int r,int L,int R) {
    	if(l==L&&r==R)	return t[u].v;
    	int mid=(l+r)>>1; pushdown(u);
    	if(R<=mid)	return qry(u*2,l,mid,L,R);
    	if(L>mid)	return qry(u*2+1,mid+1,r,L,R);
    	return Min(qry(u*2,l,mid,L,mid),qry(u*2+1,mid+1,r,mid+1,R));
    }
    int main() {
    	int opt,l,r,z;
    	read(n),read(m);
    	for(int i=1;i<=n;i++)	read(a[i]);
    	build(1,1,n);
    	for(;m;--m) {
    		read(opt),read(l),read(r);
    		switch(opt) {
    			case 1: read(z),mdy_and(1,1,n,l,r,z);break;
    			case 2: read(z),mdy_or(1,1,n,l,r,z);break;
    			default:	printf("%d
    ",qry(1,1,n,l,r));break;
    		}
    //		printf("<<< ");
    //		for(int i=1;i<=n;i++)	printf("%d ",qry(1,1,n,i,i));
    //		printf("
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    【科创人上海行】扶墙老师王福强:架构师创业要突破思维局限,技术人创业的三种模式,健康第一
    【科创人·独家】连续创业者高春辉的这六年:高强度投入打造全球领先的IP数据库
    中国确实需要大力扩充核武器
    SAP MM 可以通过STO在公司间转移质检库存?
    SAP MM 如何看一个采购申请是由APO系统创建后同步过来的?
    SAP MM 如何看一个Inbound Delivery单据相关的IDoc?
    SAP ECC & APO集成
    SAP MM 采购订单收货之后自动形成分包商库存?
    SAP MM 带有'Return'标记的STO,不能创建内向交货单?
    SAP MM 没有启用QM的前提下可以从QI库存里退货给Vendor?
  • 原文地址:https://www.cnblogs.com/daniel14311531/p/10190959.html
Copyright © 2011-2022 走看看