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) ...
随机推荐
- js 获取复选框 和 并改变状态
function checkAll() { var checkbox = document.getElementById('vegeids');// var boxes = document.getE ...
- JasperReport编译报表设计5
我们在前面的章节中产生的JasperReport模板(JRXML文件).这个文件不能直接用于生成报告.它必须被编译成JasperReport的“本地二进制"格式,称为Jasperfile.在 ...
- H5C3--设置颜色的几种方式
设置颜色的方式: 关键字:red|blue 第一种:十六进制:#ffffff 第二种:rgb(红,绿,蓝): rgb(ffff00) rgba(红,绿,蓝,透明度) 第三种:hsl(色相,饱和度,明度 ...
- 2016中国人工智能企业TOP100, CBinsight2016年100家人工智能公司
2016中国人工智能企业TOP100 不论在学界还是业界,均有代表人物对人工智能表示了担忧,如史蒂芬·霍金和比尔·盖茨.尽管如此,国内外科技巨头都积极发力人工智能,一波波创业者也相继涌入.人工智能成为 ...
- C#调用C++ DLL动态库的两种方式
第一种方式:C++导出函数, c#dllimport 的方式 在很多地方都看到过,如[dllimport "user32.dll"]这种代码,调用windows API,就是通过这 ...
- python基础--闭包and装饰器
闭包函数:函数内部定义的函数:引用了外部变量但非全局变量 装饰器:有了闭包的概念再去理解装饰器就会相对容易一些.python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加 ...
- 2018-8-10-如何使用-C#-爬虫获得专栏博客更新排行
title author date CreateTime categories 如何使用 C# 爬虫获得专栏博客更新排行 lindexi 2018-08-10 19:16:51 +0800 2018- ...
- 微信小程序之组件的集合(一)
小程序中是很强调组件中开发的,我们看到的页面是由许多组件组成的,但是这些组件是如何组合在一起的呢?来学习一下! 一.组件中数据的获取 接着上一篇文章,继续来优化代码,如何把从服务器上获取的数据显示到 ...
- js实现HashTable
1.哈希表使用键值对进行的数据储存,在数据的存储位置和它的关键字之间建立一一对应的关系,从而使关键字和结构中的一个唯一的存储位置相对应,所以在检索数据时 只需要根据这个关系便可以快速定位到要找的数据. ...
- Django项目:CRM(客户关系管理系统)--16--08PerfectCRM实现King_admin显示注册表的字段表头
# king_urls.py # ————————02PerfectCRM创建ADMIN页面———————— from django.conf.urls import url from king_ad ...