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

    https://loj.ac/p/6507

    考虑线段树维护区间或 (o) 和区间与 (a),对于区间和 (k) 与的操作:

    • (o operatorname{and} k=o),则说明每个此区间有 (1) 的位 (k) 也都是 (1),操作在此区间没用
    • (o operatorname{and} k=a operatorname{and} k),则说明 (k) 只在区间所有数 都有 或 都没有 (1) 的位置上有 (1),那么可以打标记的同时维护最小值
    • 其他情况递归下去

    或操作类似

    关于复杂度,设 (u) 节点的势能是 满足区间中存在两数的这一二进制位不同 的二进制位数
    那么初始势能是 (O(nlog nlog A)),每次修改操作会增加最多 (O(log nlog A)) 的势能
    而每次暴力递归一层,至少会减少 (1) 的势能,因此复杂度 (O(nlog nlog A))

    
    #define lim 2147483647
    #define N 500006
    struct Node{
    	Node *ls,*rs;
    	int _and,_or,min;
    	int tand,tor;
    	inline void pushup(){
    		min=std::min(ls->min,rs->min);
    		_and=ls->_and&rs->_and;_or=ls->_or|rs->_or;
    	}
    	inline void And(int k){_and&=k;_or&=k;min&=k;tand&=k;tor&=k;}
    	inline void Or(int k){_and|=k;_or|=k;min|=k;tand|=k;tor|=k;}
    	inline void pushdown(){
    		ls->And(tand);ls->Or(tor);
    		rs->And(tand);rs->Or(tor);
    		tand=lim;tor=0;
    	}
    }dizhi[N*2],*root;int tot;
    int a[N];
    void build(Node *&tree,int l,int r){
    	tree=&dizhi[++tot];
    	tree->tand=lim;
    	if(l==r) return tree->_and=tree->_or=tree->min=a[l],void();
    	int mid=(l+r)>>1;
    	build(tree->ls,l,mid);build(tree->rs,mid+1,r);
    	tree->pushup();
    }
    void And(Node *tree,int l,int r,int ql,int qr,int k){
    	if((tree->_or&k)==tree->_or) return;
    	if(ql<=l&&r<=qr&&(tree->_and&k)==(tree->_or&k)) return tree->And(k),void();
    	tree->pushdown();
    	int mid=(l+r)>>1;
    	if(ql<=mid) And(tree->ls,l,mid,ql,qr,k);
    	if(qr>mid) And(tree->rs,mid+1,r,ql,qr,k);
    	tree->pushup();
    }
    void Or(Node *tree,int l,int r,int ql,int qr,int k){
    	if((tree->_and|k)==tree->_and) return;
    	if(ql<=l&&r<=qr&&(tree->_and|k)==(tree->_or|k)) return tree->Or(k),void();
    	tree->pushdown();
    	int mid=(l+r)>>1;
    	if(ql<=mid) Or(tree->ls,l,mid,ql,qr,k);
    	if(qr>mid) Or(tree->rs,mid+1,r,ql,qr,k);
    	tree->pushup();
    }
    int getMin(Node *tree,int l,int r,int ql,int qr){
    	if(ql<=l&&r<=qr) return tree->min;
    	tree->pushdown();
    	int mid=(l+r)>>1,ans=lim;
    	if(ql<=mid) ans=getMin(tree->ls,l,mid,ql,qr);
    	if(qr>mid) ans=std::min(ans,getMin(tree->rs,mid+1,r,ql,qr));
    	return ans;
    }
    int main(){
    //		freopen("1.in","r",stdin);
    	int n=read(),m=read();
    	for(int i=1;i<=n;i++) a[i]=read();
    	build(root,1,n);
    	while(m--){
    		int op=read(),l=read(),r=read();
    		if(op==1) And(root,1,n,l,r,read());
    		else if(op==2) Or(root,1,n,l,r,read());
    		else if(op==3) printf("%d
    ",getMin(root,1,n,l,r));
    	}
    	return 0;
    }
    
  • 相关阅读:
    第7.10节 Python类中的实例变量定义与使用
    第7.9节 案例详解:Python类封装
    第7.8节 Python中隐秘的类封装方法
    第7.7节 案例详解:Python类继承机制
    第7.6节 Python中类的继承机制详述
    第7.5节 揭开Python类中self的面纱
    第7.4节 Python中与众不同的类
    第7.3节 Python特色的面向对象设计:协议、多态及鸭子类型
    第7.2节 关于面向对象设计的一些思考
    (独孤九剑)--流程控制
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/15389082.html
Copyright © 2011-2022 走看看