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

解题关键:

1、双标记线段树,注意优先级(超时)

当涉及多重标记时,定义出标记的优先级,修改操作时用优先级高(先下放)的修正优先级低(后下放)的来保证标记的正确性。

同时维护了区间and,区间or

https://blog.csdn.net/PhantomAgony/article/details/78810369

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
#define MAXN 100010
#define INF 0x7fffffff
#define lc rt<<1
#define rc rt<<1|1
namespace IO{
char buf[<<],*fs,*ft;
inline char gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,,<<,stdin),fs==ft))?:*fs++;}
inline int qr(){
int x=,rev=,ch=gc();
while(ch<''||ch>''){if(ch=='-')rev=;ch=gc();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=gc();}
return rev?-x:x;}
}using namespace IO;
using namespace std;
int N,Q,tago[MAXN<<],taga[MAXN<<],vo[MAXN<<],va[MAXN<<],ma[MAXN<<],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]=;
}
} 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)>>;
Build(l,mid,lc);
Build(mid+,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)){//都为1或都为0
PutAnd(rt,x);
return;
}
}
else{//区间|
if((x&(va[rt]|(vo[rt]^INF)))==x){
PutOr(rt,x);
return;
}
}
}
Down(rt);
int mid=l+r>>;
if(L<=mid)Modify(L,R,l,mid,lc,x,flag);
if(R>mid)Modify(L,R,mid+,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)>>,ret=;
Down(rt);
if(L<=mid)ret=Query(L,R,l,mid,lc);
if(R>mid)ret=max(ret,Query(L,R,mid+,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=;i<=N;i++)a[i]=qr();
Build(,N,);
while(Q--){
op=qr();x=qr();y=qr();
if(op==)z=qr(),Modify(x,y,,N,,z,);
else if(op==)z=qr(),Modify(x,y,,N,,z,);
else printf("%d\n",Query(x,y,,N,));
}
return ;
}

2、一个same维护区间内相同的位

#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = ;
const int bas = 0x7fffffff;
int T[maxn<<],lazy[maxn<<],sam[maxn<<];
int a[maxn];
inline void update(int rt){
T[rt]=max(T[rt<<],T[rt<<|]);
sam[rt]=(sam[rt<<]&sam[rt<<|])&(~(T[rt<<]^T[rt<<|]));
} inline void pushdown(int rt){
if(!lazy[rt]) return ;
T[rt<<]+=lazy[rt];lazy[rt<<]+=lazy[rt];
T[rt<<|]+=lazy[rt];lazy[rt<<|]+=lazy[rt];
lazy[rt]=;
} void build(int rt,int l,int r){
if(l==r){
T[rt]=a[l];
sam[rt]=bas;//全1
return;
}
int mid=l+r>>;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
update(rt);
}
int L,R,val,tmp; inline bool check_a(int rt){
tmp=(val^bas);
return (tmp&sam[rt])==tmp;
} void modify_a(int rt,int l,int r){
if(L<=l&&r<=R&&check_a(rt)){
tmp=(T[rt]&val)-T[rt];
lazy[rt]+=tmp;
T[rt]+=tmp;
return;
}
pushdown(rt);
int mid=l+r>>;
if(L<=mid) modify_a(rt<<,l,mid);
if(R>mid) modify_a(rt<<|,mid+,r);
update(rt);
}
void modify_o(int rt,int l,int r){
if(L<=l&&r<=R&&(sam[rt]&val)==val){
tmp=(T[rt]|val)-T[rt];
lazy[rt]+=tmp;
T[rt]+=tmp;
return;
}
int mid=l+r>>;
pushdown(rt);
if(L<=mid) modify_o(rt<<,l,mid);
if(R>mid) modify_o(rt<<|,mid+,r);
update(rt);
} int query(int rt,int l,int r){
if(L<=l&&r<=R) return T[rt];
pushdown(rt);
int mid=l+r>>,res=;
if(L<=mid) res=max(res,query(rt<<,l,mid));
if(R>mid) res=max(res,query(rt<<|,mid+,r));
return res;
}
int main(){
freopen("series_wei.in","r",stdin);
freopen("series_wei.out","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",a+i);
build(,,n);
int opt;
while(m--){
scanf("%d%d%d",&opt,&L,&R);
if(opt == ) scanf("%d",&val),modify_a(,,n);
else if(opt == ) scanf("%d",&val),modify_o(,,n);
else printf("%d\n",query(,,n));
}
return ;
}

[cogs2638]数列操作ψ(双标记线段树)的更多相关文章

  1. 2018.07.31cogs2964. 数列操作η(线段树)

    传送门 线段树基本操作. 给出一个排列b,有一个初始值都为0的数组a,维护区间加1,区间统计区间∑(ai/bi)" role="presentation" style=& ...

  2. 值得一做》关于双标记线段树两三事BZOJ 1798 (NORMAL-)

    这是一道双标记线段树的题,很让人很好的预习/学习/复习线段树,我不知道它能让别人学习什么,反正让我对线段树的了解更加深刻. 题目没什么好讲的,程序也没什么好讲的,所以也没有什么题解,但是值得一做 给出 ...

  3. BZOJ_1858_[Scoi2010]序列操作_线段树

    BZOJ_1858_[Scoi2010]序列操作_线段树 Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询 ...

  4. 【BZOJ1858】序列操作(线段树)

    [BZOJ1858]序列操作(线段树) 题面 BZOJ 题解 这题思路很简单,细节很烦,很码 维护区间翻转和区间赋值标记 当打到区间赋值标记时直接覆盖掉翻转标记 下放标记的时候先放赋值标记再放翻转标记 ...

  5. 【BZOJ2962】序列操作(线段树)

    [BZOJ2962]序列操作(线段树) 题面 BZOJ 题解 设\(s[i]\)表示区间内选择\(i\)个数的乘积的和 考虑如何向上合并? \(s[k]=\sum_{i=0}^klson.s[i]*r ...

  6. 【双标记线段树】bzoj1798维护序列seq

    一.题目 描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列 ...

  7. CDOJ 1157 数列(seq) 分块+线段树

    数列(seq) Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1157 Desc ...

  8. [LuoguP1438]无聊的数列(差分+线段树/树状数组)

    \(Link\) \(\color{red}{\mathcal{Description}}\) 给你一个数列,要求支持单点查询\(and\)区间加等差数列. \(\color{red}{\mathca ...

  9. [bzoj2962]序列操作_线段树_区间卷积

    序列操作 bzoj-2962 题目大意:给定一个n个数的正整数序列,m次操作.支持:1.区间加:2.区间取相反数:3.区间求选c个数的乘积和. 注释:$1\le n,m\le 5\cdot 10^4$ ...

随机推荐

  1. C#中的依赖注入那些事儿

    目录 目录 1 IGame游戏公司的故事 1.1 讨论会 1.2 实习生小李的实现方法 1.3 架构师的建议 1.4 小李的小结 2 探究依赖注入 2.1 故事的启迪 2.2 正式定义依赖注入 3 依 ...

  2. 没有80端口的备案域名,如何做微信公众平台的开发?本文介绍可以通过任何域名来做开发,www.baidu.com和www.163.com和www.so.com这样的域名都可以

    1.首先做过微信开发的朋友都知道,微信后台需要绑定80端口的备案域名,如果此时手上没有80端口的备案域名就不能进行开发了吗?当然不是 首先在这些地方绑定一个备案域名,国内公司的网址基本上是有备案的如w ...

  3. (转)Inno Setup入门(九)——修改安装过程中的文字显示

    本文转载自:http://blog.csdn.net/yushanddddfenghailin/article/details/17250837 前面说到过可以使用不用的语言文件实现不同的显示方式,方 ...

  4. Django 组件-中间件

    中间件 中间件的概念 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好 ...

  5. dom4j使用的小例子

    product.xml: <?xml version="1.0" encoding="UTF-8"?> <root> <produ ...

  6. Solr入门和实践以及我对Solr的8点理解

    友情提示Solr的内容还是比较多的,一篇文章只能讲解一部分.全面介绍,没兴趣,没时间,也没能力,回报还不大.本文只写点我认为比较重要的知识点,独特的个人想法.仅供参考哦,更多细节需要自己去琢磨. 概述 ...

  7. EFCodeFirst使用Nuget更新数据库

    在MVC开发中,习惯于使用EF作为数据库操作,相对于传统的Ado.Net的数据库操作方式,EF大大的节省了我们手写SQL语句的时间,即便是传统的使用代码生成的方式.EF操作数据库目前分为两种大的方式. ...

  8. Oracle归档与非归档模式

    一.什么是Oracle归档模式 Oracle数据库有联机重做日志,这个日志是记录对数据库所做的修改,比如插入,删除,更新数据等,对这些操作都会记录在联机重做日志里.一般数据库至少要有2个联机重做日志组 ...

  9. 【BZOJ】1030: [JSOI2007]文本生成器(AC自动机+dp)

    题目 传送门:QWQ 传送到洛谷QWQ 分析 我一开始也不会做这题的,后来看了很多网上的题解,终于AC了.(我好菜啊) 主要参考:传送门QWQ 直接搞非常麻烦,反正我是不会做.于是考虑求反,即求有多少 ...

  10. 判断和调整library cache,data dictionary cache,buffer cache性能

    Oracle SGA是oracle的内存结构,存放着oracle通过oracle进程读写的内存数据.sga分为好多组件,比如shared pool,buffer cache,redo log buff ...