本篇题解参考了这个博客

题目链接

我们利用线段树来维护区间第最大值,考虑如何修改

每一次进行与操作时只有z的二进制为0的位会产生影响

每一次进行或操作时只有z的二进制为1的位会产生影响

所以只要该区间二进制相同的位刚好是z会产生影响的二进制为位

那么该修改对这个区间的影响是一样的,我们就可以用一个区间修改的标记进行维护

标记下传也很简单

现在的问题是如何快速合并两个区间

我们用0表示该区间第k位二进制位不同,1表示相同

显然可以用一个int来存下

左右区间相同的二进制位一定是左边区间相同的和右边区间相同的二进制位的交集的子集

显然 same[l]&same[r]就是交集 但是我们还要判断第k位在左右区间究竟是否相同

有可能左边第k位都是0,右边第k位全是1

我们只要左右区间各取一个代表元素,然后将这两个代表元素的相同位取出来与一下(same[l] & same[r])就好了

复杂度度大概是nlogn

# include<cstdio>
# include<algorithm>
# include<cstdlib>
# include<ctime>
# include<iostream>
using namespace std;
const int mn = ;
int a[mn];
struct segment{
int mx[mn*],sam[mn*],tag[mn*];
int bas;
void updown(int cur)
{
mx[cur]=max(mx[cur<<],mx[cur<<|]);
sam[cur]=((sam[cur<<] & sam[cur<<|]) & (~(mx[cur<<] ^ mx[cur<<|])));
}
void pushdown(int cur)
{
if(tag[cur])
{
mx[cur<<]+=tag[cur];
mx[cur<<|]+=tag[cur];
tag[cur<<]+=tag[cur];
tag[cur<<|]+=tag[cur];
tag[cur]=;
}
}
void build(int l,int r,int cur)
{
if(l==r)
{
mx[cur]=a[l];
sam[cur]=bas;
return ;
}
int mid=l+r>>;
build(l,mid,cur<<);
build(mid+,r,cur<<|);
updown(cur);
}
bool check(int cur,int val)
{
int tmp=(val ^ bas);
return (tmp & sam[cur])==tmp;
}
void update1(int l,int r,int cur,int L,int R,int z)
{
if(l>R || r<L) return ;
if(l>=L && r<=R && check(cur,z)) {
int tmp = (mx[cur] & z) - mx[cur];
tag[cur]+=tmp; mx[cur]+=tmp;
return ;
}
int mid=l+r>>;
pushdown(cur);
update1(l,mid,cur<<,L,R,z);
update1(mid+,r,cur<<|,L,R,z);
updown(cur);
}
void update2(int l,int r,int cur,int L,int R,int z)
{
if(l>R || r<L) return ;
if(l>=L && r<=R && ((z& sam[cur]) ==z)) {
int tmp = (mx[cur] | z) - mx[cur];
tag[cur]+=tmp; mx[cur] +=tmp;
return ;
}
int mid=l+r>>;
pushdown(cur);
update2(l,mid,cur<<,L,R,z);
update2(mid+,r,cur<<|,L,R,z);
updown(cur);
}
int query(int l,int r,int cur,int L,int R)
{
if(l>=L && r<=R) return mx[cur];
if(l>R || r<L) return ;
int mid=l+r>>;
pushdown(cur);
int ret=;
ret=max(query(l,mid,cur<<,L,R),query(mid+,r,cur<<|,L,R));
updown(cur);
return ret;
}
}T;
int n,m;
int main()
{
int opt,x,y,z;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
T.bas=;
T.build(,n,);
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&opt,&x,&y);
if(opt==)
{
scanf("%d",&z);
T.update1(,n,,x,y,z);
}
else if(opt==)
{
scanf("%d",&z);
T.update2(,n,,x,y,z);
}
else printf("%d\n",T.query(,n,,x,y));
}
return ;
}

COGS-2638 区间与,异或,询问max的更多相关文章

  1. COGS 2638. 数列操作ψ 线段树

    传送门 : COGS 2638. 数列操作ψ 线段树 这道题让我们维护区间最大值,以及维护区间and,or一个数 我们考虑用线段树进行维护,这时候我们就要用到吉司机线段树啦 QAQ 由于发现若干次an ...

  2. [HDU] 5306 Gorgeous Sequence [区间取min&求和&求max]

    题解: 线段树维护区间取min求和求max 维护最小值以及个数,次小值 标记清除时,分情况讨论 当lazy>max1 退出 当max1>lazy>max2(注意不要有等号) 更新 否 ...

  3. 51Nod XOR key —— 区间最大异或值 可持久化字典树

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1295 1295 XOR key  题目来源: HackerRa ...

  4. 51Nod - 1295:XOR key (可持久化Trie求区间最大异或)

    给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求ALL 至 ARR 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值 ...

  5. Wannafly Winter Camp 2020 Day 6H 异或询问 - 二分

    给定一个长 \(n\) 的序列 \(a_1,\dots,a_n\),定义 \(f(x)\) 为有多少个 \(a_i \leq x\) 有 \(q\) 次询问,每次给定 \(l,r,x\),求 \(\s ...

  6. Atcoder Regular 098 区间Pre=Xor Q询问区间连续K去最小值最小极差

    C 用scanf("%s")就会WA..不知道为什么 /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset ...

  7. 询问任意区间的min,max,gcd,lcm,sum,xor,or,and

    给我们n个数,然后有m个询问,每个询问为L,R,询问区间[L,R]的最大最小值,最小公约数,最大公约数,和,异或,或,且 这些问题通通可以用RMQ的思想来解决. 以下用xor来作为例子 设dp[i][ ...

  8. 【GDKOI2016Day1T1-魔卡少女】【拆位】线段树维护区间内所有连续子区间的异或和

    题意:给出N个数,M个操作.操作有修改和询问两种,每次修改将一个数改成另一个数,每次询问一个区间的所有连续子区间的异或和.n,m<=100000,ai<=1000 题解: 当年(其实也就是 ...

  9. Atcoder Beginner Contest 121 D - XOR World(区间异或和)

    题目链接:https://atcoder.jp/contests/abc121/tasks/abc121_d 题目很裸(Atcoder好像都比较裸 就给一个区间求异或和 n到1e12 肯定不能O(n) ...

随机推荐

  1. Luogu P1092 虫食算(枚举+剪枝)

    P1092 虫食算 题面 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 + 8468#6633 4 ...

  2. php数据几行代码导出到excel(非插件)

    <?php header("Content-type:application/vnd.ms-excel"); header("Content-Disposition ...

  3. mybatis深入理解(六)-----MyBatis的二级缓存的设计原理

    MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 1.MyBatis的缓存机制整体设计以及 ...

  4. OpenLayers测量距离和面积

    <!DOCTYPE html> <html> <head> <title>测量距离和面积</title> <meta http-equ ...

  5. tumblr arch information

    http://developer.51cto.com/art/201305/395757.htm 每月超过30%的增长当然不可能没有挑战,其中可靠性问题尤为艰巨.每天5亿次浏览量,峰值每秒4万次请求, ...

  6. GIT → 11:Git 工作流与实战演练

    GIT → 11:Git 工作流与实战演练

  7. Mac OS 安装 独立的asio库

    先安装boost,见前文,然后上官网下载不带boost的asio,版本为:asio-1.12.2 cd到下载的库目录,配置 ./configure --with-boost="boost的安 ...

  8. Linux图形界面安装卸载,与命令界面之间的转换

    1.图形界面与命令界面之间的转换 软切换: ctrl+alt+F6进入命令行模式,ctrl+alt+F1进入图形界面,(有些情况下不管用) 注意: 该方法转为命令行界面后图形界面依然占据着系统资源. ...

  9. Django 的学习(2) 从adminuser到配置

    创建一个superuser python manage.py createsuperuser 然后是密码邮箱用户名 You should see a few types of editable con ...

  10. Redhat/Fedora 或类似系统, 配置网络的工具介绍

    在Redhat早期的版本中, 有linuxconf .redhat-config-network .netconfig 等工具: 在Redhat/Fedora 最新的版本有 system-config ...