本篇题解参考了这个博客

题目链接

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

每一次进行与操作时只有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. [BZOJ2729]排队

    数学知识 排列  A(n,m)从n个元素中选出m个的不同的排列数  A(n,m)=n!/(n-m)! 组合  C(n,m)从n个元素中选出m个的不同的方案数  C(n,m)=n!/(m!*(n-m)! ...

  2. Dom直接选择器

    Dom直接选择器 <!DOCTYPE html> <!--Dom间接选择器--> <html lang="en"> <head> & ...

  3. php静态变量问题

    <?php$a=0; function test(){ static $a=0; $a+=1; echo $a; }test(); test(); ?>1.static是与销毁时间有关,与 ...

  4. springmvc配置不拦截静态资源

    <mvc:resources mapping="/js/**" location="/js/"/>

  5. JAVA邀请码生成器

    code import java.util.Random; /** * 邀请码生成器,算法原理:<br/> * 1) 获取id: 1127738 <br/> * 2) 使用自定 ...

  6. day36 11-Hibernate中的事务:当前线程中的session

    如果你没有同一个session开启事务的话,那它两是一个独立的事务.必须是同一个session才有效.它给我们提供一个本地线程的session.这个session就保证了你是同一个session.其实 ...

  7. Codeforces 608E. Marbles

    E. Marbles time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  8. web前端开发必备技术

    1.Vue.js是什么? Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核心库只关注 ...

  9. Calendar to julian date format

    1.JULIAN DATE 定义 2.示例: 定义枚举: public enum JulianDateType    {        /// <summary>        /// J ...

  10. 实践中了解到的CSS样式的优先级

    CSS三大特性——继承.优先级和层叠.这是在精通CSS中重点强调的内容. 继承即子类元素继承父类的样式,常用的可继承样式有:color,font,line-height,list-style,text ...