首先我们考虑,对于And 和 Or 操作,对于操作位上只有And 0 和 Or 1 是有效果的。

我们注意到如果区间内需要改动的操作位上的数字都相同,那么是可以区间取与以及区间取或的。

那其实可以维护出这个区间的$区间与x和区间或y$

我们考虑 $某一位上 x\;  xor \; y == 1 时$

必定是$x 那一位上 是0 \; y 那一位上是1$

因为显然 $如果x那一位上是1,那么y那一位上必然是1, y那一位上是0, x 那一位上必然是0$

那我们再考虑区间与的操作,我们令 $S = (1 << 31) - 1, 令val 表示需要与的数$

当 $(x \; xor \; y) \; and \; (S - val) == 0 的时候$

这个时候可以理解为在不需要与0的位置上,这个区间内都是1或者都是0,即这些不相关位对我们的区间取与操作不会有影响。

再考虑如何标记$lazy, 对And 和 Or 分别设置一个lazyA 和 lazyO $

$我们注意到,要取与的时候,把lazyA 一并与上, 并且把lazyO也要与上$

取或的时候只给$lazyO$取或就可以。

区间取或的操作分析同理。

再简陋的证明一下复杂度:

假设我们考虑要处理的一段区间不能进行区间处理,需要一位一位处理,但是我们这次处理之后这一段区间就可以区间处理了

再考虑,对于一段已经完好的区间,我们对它区间处理,它就会分成三段,但实际上这次的处理是$log的$

再考虑下一次处理,实际上两头又是好的,感觉又是$log$..

好吧 不口胡了,还是放官方的复杂度证明吧。。

https://csacademy.com/contest/round-70/task/and-or-max/solution

 #include <bits/stdc++.h>
using namespace std; #define N 200010
int n, q, arr[N], S = ( << ) - ; struct SEG
{
struct node
{
int Max, A, O, lazyA, lazyO;
node() {}
node(int x)
{
Max = A = O = x;
lazyA = S;
lazyO = ;
}
node operator + (const node &r) const
{
node res = node();
res.Max = max(Max, r.Max);
res.A = A & r.A;
res.O = O | r.O;
return res;
}
void add(int And, int Or)
{
Max = Max & And | Or;
A = A & And | Or;
O = O & And | Or;
lazyA = lazyA & And;
lazyO = lazyO & And | Or;
}
}a[N << ];
void build(int id, int l, int r)
{
if (l == r)
{
a[id] = node(arr[l]);
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
a[id] = a[id << ] + a[id << | ];
}
void pushdown(int id)
{
if (a[id].lazyA != S || a[id].lazyO)
{
a[id << ].add(a[id].lazyA, a[id].lazyO);
a[id << | ].add(a[id].lazyA, a[id].lazyO);
a[id].lazyA = S;
a[id].lazyO = ;
}
}
void updateA(int id, int l, int r, int ql, int qr, int val)
{
if (l >= ql && r <= qr && !((a[id].A ^ a[id].O) & (S ^ val)))
{
a[id].add(val, );
return;
}
pushdown(id);
int mid = (l + r) >> ;
if (ql <= mid) updateA(id << , l, mid, ql, qr, val);
if (qr > mid) updateA(id << | , mid + , r, ql, qr, val);
a[id] = a[id << ] + a[id << | ];
}
void updateO(int id, int l, int r, int ql, int qr, int val)
{
if (l >= ql && r <= qr && !((a[id].A ^ a[id].O) & val))
{
a[id].add(S, val);
return;
}
pushdown(id);
int mid = (l + r) >> ;
if (ql <= mid) updateO(id << , l, mid, ql, qr, val);
if (qr > mid) updateO(id << | , mid + , r, ql, qr, val);
a[id] = a[id << ] + a[id << | ];
}
int query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return a[id].Max;
pushdown(id);
int mid = (l + r) >> ;
int res = ;
if (ql <= mid) res = max(res, query(id << , l, mid, ql, qr));
if (qr > mid) res = max(res, query(id << | , mid + , r, ql, qr));
a[id] = a[id << ] + a[id << | ];
return res;
}
}seg; void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
seg.build(, , n);
for (int qq = , op, l, r, x; qq <= q; ++qq)
{
scanf("%d%d%d", &op, &l, &r);
if (op == ) printf("%d\n", seg.query(, , n, l, r));
else
{
scanf("%d", &x);
if (op == ) seg.updateA(, , n, l, r, x);
else seg.updateO(, , n, l, r, x);
}
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

BZOJ 5312: 冒险的更多相关文章

  1. 【刷题】BZOJ 5312 冒险

    Description Kaiser终于成为冒险协会的一员,这次冒险协会派他去冒险,他来到一处古墓,却被大门上的守护神挡住了去路,守护神给出了一个问题, 只有答对了问题才能进入,守护神给出了一个自然数 ...

  2. BZOJ.5312.冒险(线段树)

    题目链接 \(Description\) 维护一个序列,支持区间and/or一个数.区间查询最大值. \(Solution\) 维护区间最大值?好像没什么用,修改的时候和暴力差不多. 我们发现有时候区 ...

  3. bzoj 4695: 最假女选手 && Gorgeous Sequence HDU - 5306 && (bzoj5312 冒险 || 小B的序列) && bzoj4355: Play with sequence

    算导: 核算法 给每种操作一个摊还代价(是手工定义的),给数据结构中某些东西一个“信用”值(不是手动定义的,是被动产生的),摊还代价等于实际代价+信用变化量. 当实际代价小于摊还代价时,增加等于差额的 ...

  4. BZOJ5312:冒险——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5312 Kaiser终于成为冒险协会的一员,这次冒险协会派他去冒险,他来到一处古墓,却被大门上的守护 ...

  5. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  6. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  7. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  8. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  9. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

随机推荐

  1. PHP 程序员面试常问的问题

    1. Include 与 require的区别,require和require_once的效率哪个高? Php在遇到include时就解释一次,如果页面中出现10次include,php就解释10次, ...

  2. 【Python】求素数-稍加优化

    print 'Find prime number smaller then input number \n' print 'Please input a number:' import datetim ...

  3. python 之 内置函数大全

    一.罗列全部的内置函数 戳:https://docs.python.org/2/library/functions.html 二.range.xrange(迭代器) 无论是range()还是xrang ...

  4. js引入script

    引入再删除,节省资源. <!DOCTYPE html> <html> <head lang="en"> <meta charset=&qu ...

  5. JS制作一个通用的商城版历史浏览记录

    正在开发一个b2c的国外商城,昨天做了一个历史浏览记录发出来跟大家分享一下. JS: //cookie相关函数 function getCookieVal(offset) {    var endst ...

  6. [LeetCode] Reverse Lists

    Well, since the head pointer may also be modified, we create a new_head that points to it to facilit ...

  7. 【转】 JS实现HTML标签转义及反转义

    原文地址:http://blog.600km.xyz/2015/12/15/js-encode-html-tags/ 简单说一下业务场景,前台用户通过input输入内容,在离开焦点时,将内容在div中 ...

  8. eslint Rules

    Rules 为了让你对规则有个更好的理解,ESLint 对其进行了分门别类. 所有的规则默认都是禁用的.在配置文件中,使用 "extends": "eslint:reco ...

  9. 【IDEA】启动项目报错:3 字节的 UTF-8 序列的字节 3 无效

    一.报错和原因: 项目起服务出错.具体报错就不贴了,报错主要是"3 字节的 UTF-8 序列的字节 3 无效". 分析:主要就是项目编码问题,IDEA中估计就是配置不对,没必要纠结 ...

  10. 动态代理:JDK原生动态代理(Java Proxy)和CGLIB动态代理原理+附静态态代理

    本文只是对原文的梳理总结,以及自行理解.自己总结的比较简单,而且不深入,不如直接看原文.不过自己梳理一遍更有助于理解. 详细可参考原文:http://www.cnblogs.com/Carpenter ...