题意:

已知\(n\)个数字,进行以下操作:

  • \(1.\)区间\([L,R]\) 按位与\(x\)
  • \(2.\)区间\([L,R]\) 按位或\(x\)
  • \(3.\)区间\([L,R]\) 询问最大值

思路:

吉司机线段树。
我们按位考虑,维护区间或\(\_or\)和区间与\(\_and\),那么得到区间非公有的\(1\)为\((\_or \oplus \_and)\),那么如果对所有的非公有的\(1\)影响都一样就不会对最大值有影响,那么就直接打标机,否则继续往下更新。即
\[ [(\_or[rt] \oplus \_and[rt]) \& x] == 0 || [(\_or[rt] \oplus \_and[rt]) \& x] == (\_or[rt] \oplus \_and[rt]) \]
时就直接打标记。

代码:

#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int maxn = 2e5 + 5;
const int MAXM = 3e6;
const ll MOD = 998244353;
const ull seed = 131;
const int INF = 0x3f3f3f3f;#define lson (rt << 1)
#define rson (rt << 1 | 1)
inline bool read(int &num){char in;bool IsN=false;in = getchar();if(in == EOF) return false;while(in != '-' && (in < '0' || in > '9')) in = getchar();if(in == '-'){ IsN = true; num = 0;}else num = in - '0';while(in = getchar(),in >= '0' && in <= '9'){num *= 10, num += in-'0';}if(IsN) num = -num;return true;
}int a[maxn], all = (1 << 21) - 1;
int _or[maxn << 2], _and[maxn << 2], Max[maxn << 2];
int lazya[maxn << 2], lazyo[maxn << 2];
inline void pushup(int rt){_or[rt] = _or[lson] | _or[rson];_and[rt] = _and[lson] & _and[rson];Max[rt] = max(Max[lson], Max[rson]);
}
inline void pushdown(int rt, int l, int r){int m = (l + r) >> 1;if(lazya[rt] != all){Max[lson] &= lazya[rt];Max[rson] &= lazya[rt];_or[lson] &= lazya[rt];_or[rson] &= lazya[rt];_and[lson] &= lazya[rt];_and[rson] &= lazya[rt];lazya[lson] &= lazya[rt];lazya[rson] &= lazya[rt];lazyo[lson] &= lazya[rt];lazyo[rson] &= lazya[rt];lazya[rt] = all;}if(lazyo[rt] != 0){Max[lson] |= lazyo[rt];Max[rson] |= lazyo[rt];_or[lson] |= lazyo[rt];_or[rson] |= lazyo[rt];_and[lson] |= lazyo[rt];_and[rson] |= lazyo[rt];lazya[lson] |= lazyo[rt];lazya[rson] |= lazyo[rt];lazyo[lson] |= lazyo[rt];lazyo[rson] |= lazyo[rt];lazyo[rt] = 0;}
}
void build(int l, int r, int rt){lazya[rt] = all, lazyo[rt] = 0;if(l == r){_and[rt] = _or[rt] = Max[rt] = a[l];return;}int m = (l + r) >> 1;build(l, m, lson);build(m + 1, r, rson);pushup(rt);
}
void update(int L, int R, int l, int r, int op, int x, int rt){if(L <= l && R >= r){if(op == 1){    //&if(((_or[rt] ^ _and[rt]) & x) == 0 || ((_or[rt] ^ _and[rt]) & x) == (_or[rt] ^ _and[rt])){   Max[rt] &= x;_or[rt] &= x;_and[rt] &= x;lazya[rt] &= x;lazyo[rt] &= x;return;}}else{   //|if(((_or[rt] ^ _and[rt]) & x) == 0 || ((_or[rt] ^ _and[rt]) & x) == (_or[rt] ^ _and[rt])){    Max[rt] |= x;_or[rt] |= x;_and[rt] |= x;lazya[rt] |= x;lazyo[rt] |= x;return;}}}int m = (l + r) >> 1;pushdown(rt, l, r);if(L <= m)update(L, R, l, m, op, x, lson);if(R > m)update(L, R, m + 1, r, op, x, rson);pushup(rt);
}
int query(int L, int R, int l, int r, int rt){if(L <= l && R >= r){return Max[rt];}pushdown(rt, l, r);int m = (l + r) >> 1, MAX = -INF;if(L <= m)MAX = max(MAX, query(L, R, l, m, lson));if(R > m)MAX = max(MAX, query(L, R, m + 1, r, rson));return MAX;}
int main(){int n, m;read(n), read(m);for(int i = 1; i <= n; i++) read(a[i]);build(1, n, 1);while(m--){int op, l, r, x;read(op), read(l), read(r);if(op < 3) read(x);if(op < 3){update(l, r, 1, n, op, x, 1);}else{printf("%d\n", query(l, r, 1, n, 1));}}return 0;
}

转载于:https://www.cnblogs.com/KirinSB/p/11512861.html

bzoj5312 冒险(吉司机线段树)题解相关推荐

  1. 势能线段树/吉司机线段树-我没有脑子

    势能线段树/吉司机线段树 BZOJ3211 花神游历各国 BZOJ5312 冒险 BZOJ4355 Play with sequence BZOJ4695 最假女选手 \(A_i = max(A_i, ...

  2. 2020ICPC(南京) - Just Another Game of Stones(吉司机线段树+博弈)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的数列 aaa,现在需要执行 mmm 次操作,每次操作分为两种类型: 1lrx1 \ l \ r \ x1 l r x:对于所有 i∈[l,r]i ...

  3. HDU - 5306 Gorgeous Sequence(吉司机线段树)

    题目链接:点击查看 题目大意:给出 1 ~ n 的区间以及 m 次操作,每次操作分为三种形式: 0 l r val:对于区间 [ l , r ] ,a[ i ] = min ( a[ i ] , va ...

  4. P6242-[模板]线段树3【吉司机线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P6242 题目大意 给出一个长度为nnn的序列aaa,mmm次要求支持操作 区间加上一个值kkk 区间所有aia_i ...

  5. P7560-[JOISC 2021 Day1]フードコート【吉司机线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P7560 题目大意 有 n n n个队列,要求支持操作: 往 [ L , R ] [L,R] [L,R]的队列中插入 ...

  6. 势能线段树(吉司机线段树)专题

    势能线段树(吉司机线段树)专题 势能线段树在近期训练时遇到了好几次,但是由于本人太懒一直没补完,结果ICPC网络赛还真就出了一道势能线段树Orz--结果当然是没做出来--痛定思痛,这回把之前欠的一块儿 ...

  7. 2022.08.21 吉司机线段树略讲

    Interpretation \color{green}{\texttt{Interpretation}} Interpretation 吉司机线段树(A.K.A. 势能线段树),个人觉得,就是对普通 ...

  8. [BZOJ5312]冒险(势能线段树)

    [BZOJ5312]冒险 维护一个长度为 n 的序列,支持 m 次操作,操作包括区间按位或一个数,区间按位与一个数,以及查询区间最大值. 线段树每个节点上维护区间与.区间或和区间最大值. 如果一次操作 ...

  9. 【模板】吉老师线段树

    ACM模板 目录 区间取最值 区间取最值 Gorgeous Sequence 区间最值操作往往采用以下办法 线段树维护: 区间最大值mx\text{mx}mx 区间严格次大值smx\text {smx ...

  10. HDU 1556 Color the Ball 线段树 题解

    本题使用线段树自然能够,由于区间的问题. 这里比較难想的就是: 1 最后更新须要查询全部叶子节点的值,故此须要使用O(nlgn)时间效率更新全部点. 2 截取区间不能有半点差错.否则答案错误. 这两点 ...

最新文章

  1. 调查:“AI红娘”来了,有一半人选择相信TA
  2. 基于ArduinoLeonardo板子的BadUSB攻击实战
  3. Python 读写文件和file对象(转)
  4. 无监督和有监督的区别_无监督元学习(Unsupervised Meta-Learning)
  5. 【遥感物候】Matlab求解一元六次多项式,计算植被生长季始期
  6. java中同步嵌套引起的死锁事例代码
  7. eval()函数和zip()函数用法、enumerate()
  8. Boostrap 响应式图像
  9. 国外优秀技术网站推荐
  10. Nginx+keepalive反向代理
  11. 使用javascript下载网络图片
  12. Subclipse in Eclipse的安装和使用
  13. 蜜蜂科技Bee+创始人贾凡、OFO创始人戴威入选高山大学2018级名单
  14. windows服务器硬盘怎么扩容,亚马逊Amazon EC2 Windows服务器磁盘扩容操作步骤
  15. c++ tuling123_现代编译原理-图灵计算机科学丛书.pdf
  16. vue中集成的ui组件库_Vue组件可使用Vault Flow通过Braintree集成PayPal付款
  17. res.send和res.sendFile
  18. 分享一个网易新闻的api接口
  19. PDFJS跨域显示PDF文件的两种方法
  20. 清醒认识数据第一步,把关数据质量

热门文章

  1. 如果你想提高创新,那么本书就是答案
  2. R语言grid包just参数如何just图形位置
  3. Django生命周期,FBV,CBV
  4. Spring cloud--鸿鹄Cloud分布式微服务云系统—Config
  5. puppet进阶指南——cron资源详解
  6. 回车跳到下一个EDIT
  7. centos 6.5环境利用iscsi搭建SAN网络存储服务及服务端target和客户端initiator配置详解...
  8. 代码设计之多渠道支付
  9. android 开源框架
  10. Https 真的安全吗?可以抓包吗?如何防止抓包吗?