• COGS2638. 数列操作ψ


    COGS2638. 数列操作ψ

    【题目描述】

    给定一个数列a,你需要支持的操作:区间and,区间or,询问区间最大值

    【输入格式】

    一行两个整数n,m,表示数列长度和操作个数。

    接下来一行有n个整数,第i个数表示ai。

    接下来m行,每一行均为以下三种操作中的一种

    1 l r val:ai=ai and val(l≤i≤r)

    2 l r val:ai=ai or val(l≤i≤r)

    3 l r:max{ai}(l≤i≤r)

    【输出格式】

    对于每一个3操作,输出一行整数表示对应的答案

    【样例输入】

    8 6
    4 0 5 7 2 9 12 8
    2 2 5 15
    1 3 5 2
    3 5 7
    1 5 7 12
    2 1 6 4
    3 2 6
    

    【样例输出】

    12
    15 
    

    【提示】

    对于20%数据,n,m≤3000

    另有20%数据,1,2操作中l=r

    另有20%数据,3操作中l=r

    对于100%数据,1≤n,m≤100000,0≤ai,val≤1e9

    保证所有操作中1≤l≤r≤n

    题解

    区间And操作相当于将区间中所有数的某些位全变成0,区间Or操作相当于将区间中所有数的某些位全变成1。

    线段树每个节点维护区间And和以及区间Or和,还要维护一个And标记一个Or标记以及区间最大值。

    标记的先后顺序是先And后Or。

    区间操作先找到区间,如果区间中所有的数要修改的那些位已经全相同,直接打上标记后返回。否则递归处理子区间。

    代码

    #include<bits/stdc++.h>
    #define MAXN 100010
    #define INF 0x7fffffff
    #define lc rt<<1
    #define rc rt<<1|1
    namespace IO{
    	char buf[1<<15],*fs,*ft;
    	inline char gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
    	inline int qr(){
    		int x=0,rev=0,ch=gc();
    		while(ch<'0'||ch>'9'){if(ch=='-')rev=1;ch=gc();}
    		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();}
    		return rev?-x:x;}
    }using namespace IO;
    using namespace std;
    int N,Q,tago[MAXN<<2],taga[MAXN<<2],vo[MAXN<<2],va[MAXN<<2],ma[MAXN<<2],a[MAXN];
    inline void Up(int rt){
    	vo[rt]=vo[lc]|vo[rc];va[rt]=va[lc]&va[rc];
    	ma[rt]=max(ma[lc],ma[rc]);
    }
    inline void PutAnd(int rt,int x){
    	taga[rt]&=x;tago[rt]&=x;
    	ma[rt]&=x;vo[rt]&=x;va[rt]&=x;
    }
    inline void PutOr(int rt,int x){
    	tago[rt]|=x;
    	ma[rt]|=x;vo[rt]|=x;va[rt]|=x;
    }
    inline void Down(int rt){
    	if(taga[rt]^INF){
    		PutAnd(lc,taga[rt]);
    		PutAnd(rc,taga[rt]);
    		taga[rt]=INF;
    	}
    	if(tago[rt]){
    		PutOr(lc,tago[rt]);
    		PutOr(rc,tago[rt]);
    		tago[rt]=0;
    	}
    }
    void Build(int l,int r,int rt){
    	taga[rt]=INF;
    	if(l==r){va[rt]=vo[rt]=ma[rt]=a[l];return;}
    	int mid=(l+r)>>1;
    	Build(l,mid,lc);Build(mid+1,r,rc);
    	Up(rt); 
    }
    void Modify(int L,int R,int l,int r,int rt,int x,bool flag){
    	if(L<=l&&R>=r){
    		if(flag){//区间& 
    			if(((x^INF)&(va[rt]|(vo[rt]^INF)))==(x^INF)){
    				PutAnd(rt,x);
    				return;
    			}
    		}
    		else{//区间| 
    			if((x&(va[rt]|(vo[rt]^INF)))==x){
    				PutOr(rt,x);
    				return;
    			}
    		} 
    	}
    	Down(rt);
    	int mid=l+r>>1;
    	if(L<=mid)Modify(L,R,l,mid,lc,x,flag);
    	if(R>mid)Modify(L,R,mid+1,r,rc,x,flag);
    	Up(rt); 
    }
    int Query(int L,int R,int l,int r,int rt){
    	if(L<=l&&R>=r)return ma[rt];
    	int mid=(l+r)>>1,ret=0;
    	Down(rt);
    	if(L<=mid)ret=Query(L,R,l,mid,lc);
    	if(R>mid)ret=max(ret,Query(L,R,mid+1,r,rc));
    	return ret; 
    }
    int op,x,y,z;
    int main(){
    	freopen("series_wei.in","r",stdin);
    	freopen("series_wei.out","w",stdout);
    	N=qr();Q=qr();
    	for(int i=1;i<=N;i++)a[i]=qr();
    	Build(1,N,1);
    	while(Q--){
    		op=qr();x=qr();y=qr();
    		if(op==1)z=qr(),Modify(x,y,1,N,1,z,1);
    		else if(op==2)z=qr(),Modify(x,y,1,N,1,z,0);
    		else printf("%d
    ",Query(x,y,1,N,1));
    	}
    	return 0;
    }
    
  • 相关阅读:
    json字符串和xml的 比较
    Python基础第十三天——sys模块、logging模块、json模块、pickle模块
    Python基础第十二天——模块的分类、时间模块、随机数模块、摘要算法模块、os模块、时间形式轮换
    Python基础第十一天——内置函数的补充、内置函数与lambda、递归
    Python基础第九天——迭代对象、 迭代器对象、生成器、三元表达式列表解析、生成器表达式
    Python基础第八天——无参装饰器、有参装饰器
    Python基础第七天——global与nonlocal、闭包函数、装饰器
    Python基础第六天——函数的使用、函数的参数、函数的返回值、函数的嵌套、命名空间、作用域、函数对象
    Python基础第五天——字符编码、文件处理、函数的使用
    Python基础第四天——字典、布尔值、集合
  • 原文地址:https://www.cnblogs.com/lrj998244353/p/8747120.html
Copyright © 2020-2023  润新知