COGS-2638 区间与,异或,询问max
本篇题解参考了这个博客
我们利用线段树来维护区间第最大值,考虑如何修改
每一次进行与操作时只有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的更多相关文章
- COGS 2638. 数列操作ψ 线段树
传送门 : COGS 2638. 数列操作ψ 线段树 这道题让我们维护区间最大值,以及维护区间and,or一个数 我们考虑用线段树进行维护,这时候我们就要用到吉司机线段树啦 QAQ 由于发现若干次an ...
- [HDU] 5306 Gorgeous Sequence [区间取min&求和&求max]
题解: 线段树维护区间取min求和求max 维护最小值以及个数,次小值 标记清除时,分情况讨论 当lazy>max1 退出 当max1>lazy>max2(注意不要有等号) 更新 否 ...
- 51Nod XOR key —— 区间最大异或值 可持久化字典树
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1295 1295 XOR key 题目来源: HackerRa ...
- 51Nod - 1295:XOR key (可持久化Trie求区间最大异或)
给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求ALL 至 ARR 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值 ...
- Wannafly Winter Camp 2020 Day 6H 异或询问 - 二分
给定一个长 \(n\) 的序列 \(a_1,\dots,a_n\),定义 \(f(x)\) 为有多少个 \(a_i \leq x\) 有 \(q\) 次询问,每次给定 \(l,r,x\),求 \(\s ...
- Atcoder Regular 098 区间Pre=Xor Q询问区间连续K去最小值最小极差
C 用scanf("%s")就会WA..不知道为什么 /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset ...
- 询问任意区间的min,max,gcd,lcm,sum,xor,or,and
给我们n个数,然后有m个询问,每个询问为L,R,询问区间[L,R]的最大最小值,最小公约数,最大公约数,和,异或,或,且 这些问题通通可以用RMQ的思想来解决. 以下用xor来作为例子 设dp[i][ ...
- 【GDKOI2016Day1T1-魔卡少女】【拆位】线段树维护区间内所有连续子区间的异或和
题意:给出N个数,M个操作.操作有修改和询问两种,每次修改将一个数改成另一个数,每次询问一个区间的所有连续子区间的异或和.n,m<=100000,ai<=1000 题解: 当年(其实也就是 ...
- Atcoder Beginner Contest 121 D - XOR World(区间异或和)
题目链接:https://atcoder.jp/contests/abc121/tasks/abc121_d 题目很裸(Atcoder好像都比较裸 就给一个区间求异或和 n到1e12 肯定不能O(n) ...
随机推荐
- 用sqoop抽取oracle 表到hbase的例子
sqoop import \-Doraoop.disabled=true \--connect jdbc:oracle:thin:@"(DESCRIPTION=(ADDRESS=(PROTO ...
- 有趣的纯CSS实现动态晴阴雨雪
我们先来看看实现的效果吧 非常的美腻,对吧.这个是纯css,且单标签实现的哦~ 先贴完整代码,我们再来看看这个里面究竟有什么可以借鉴的知识点 <!DOCTYPE html> <htm ...
- IDEA工具实现反编译操作
1.File - Settings... 2.在搜索框中输入“byte” - 勾选 Java Byte code Decompiler选项 点击 OK 键 3.弹出重启IDEA的选择框 选择“rest ...
- HTTP协议②缓存
首先介绍一下HTTP的报文信息,主要分成两个部分 1.包含属性的首部(header)---------------附加信息(cookie,缓存信息等)与缓存相关的规则信息,均包含在header中 2. ...
- IO流5 --- FileReader读入数据的基本操作 --- 技术搬运工(尚硅谷)
FileReader 字符输入流 @Test public void test1(){ File file = new File("hello.txt"); FileReader ...
- neo4j中对节点关系和聚类的思考
由于neo4j在查找过程中具有事务,所以查询的速度非常慢!给出的建议如下: 一,将所有查询放在一个Session中,当所有查询完毕以后在关闭Driver和Session: 二,使用neo4j连接池,使 ...
- 2019-9-2-C#判断文件是否被混淆
title author date CreateTime categories C#判断文件是否被混淆 lindexi 2019-09-02 12:57:37 +0800 2018-2-13 17:2 ...
- VisualTreeHelper使用——使用BFS实现高效率的视觉对象搜索
BFS,即广度优先搜索,是一种典型的图论算法.BFS算法与DFS(深度优先搜索)算法相对应,都是寻找图论中寻路的常用算法,两者的实现各有优点. 其中DFS算法常用递归实现,也就是常见的一条路找到黑再找 ...
- [运维]ESXI Web Client 标签: vmware运维服务器 2017-05-28 20:59 597人阅读 评论(9)
ESXI安装完成之后,配置好ip,我们就可以使用了?那么如何使用呢?一般来说有两种方式,一种是安装专门的管理客户端,client端,另一种更加方便,就是使用web client端. 下面来介绍一下es ...
- 【水滴石穿】douban-movies-react-native
这个项目的话,倒是可以做一个支架页面,就是你需要什么东西,你就可以在里面加,不过也是比较难的地方 就是数据流,数据处理的部分.react可以处理数据的方式很多,没有见过类似于古老的vue时候可以使用的 ...