BZOJ 5312: 冒险
首先我们考虑,对于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: 冒险的更多相关文章
- 【刷题】BZOJ 5312 冒险
Description Kaiser终于成为冒险协会的一员,这次冒险协会派他去冒险,他来到一处古墓,却被大门上的守护神挡住了去路,守护神给出了一个问题, 只有答对了问题才能进入,守护神给出了一个自然数 ...
- BZOJ.5312.冒险(线段树)
题目链接 \(Description\) 维护一个序列,支持区间and/or一个数.区间查询最大值. \(Solution\) 维护区间最大值?好像没什么用,修改的时候和暴力差不多. 我们发现有时候区 ...
- bzoj 4695: 最假女选手 && Gorgeous Sequence HDU - 5306 && (bzoj5312 冒险 || 小B的序列) && bzoj4355: Play with sequence
算导: 核算法 给每种操作一个摊还代价(是手工定义的),给数据结构中某些东西一个“信用”值(不是手动定义的,是被动产生的),摊还代价等于实际代价+信用变化量. 当实际代价小于摊还代价时,增加等于差额的 ...
- BZOJ5312:冒险——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5312 Kaiser终于成为冒险协会的一员,这次冒险协会派他去冒险,他来到一处古墓,却被大门上的守护 ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
随机推荐
- textarea去掉边框
<textarea style="BORDER-BOTTOM: 0px solid; BORDER-LEFT: 0px solid; BORDER-RIGHT: 0px solid; ...
- php ocket通信机制
php 实例说明 socket通信机制 一,socket是什么 什么是socket 所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通 ...
- 第二百一十八节,jQuery EasyUI,TimeSpinner(时间微调)组件
jQuery EasyUI,TimeSpinner(时间微调)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 TimeSpinner(时间微 ...
- 出售 unity3d串口插件
出售unity3d串口插件 利用C++编写,解决了mono库 serialport的bug. serialport串口的bug地方在于: 1.有一些数据无法收到. 2.会丢失第一个字节. 3.延迟 我 ...
- 支持IE低版本的上传 大文件切割上传 断点续传 秒传
1. http://files.cnblogs.com/files/blackice/UploadDemo.rar 此demo是使用的 swfupload 2.http://download.csdn ...
- debug命令
debug -r 查看寄存器-a 输入指令-t 执形命令 通用寄存器:AX=AH+ALBX=BH+BLCX=CH+CLDX=DH+DL 2Byte 16bitFFFF0-(2的16次方减1) debu ...
- 对Linux命令进一步学习vim(二)
今天,进一步学习Linux相关的命令,可能会有重复的地方,但学习本来就是不断重复的过程.故作小记! 1.安装了:vim ,,,一款Linux爱好者经常用到的ide sudo apt-get inst ...
- chrome vim设置
chrome vi 插件:Vrome 配置文件如下 set hintkeys=asdfghjkl;" 把默认使用数字来完成提示改为使用键盘上的这几个键map j 10jmap k 10k&q ...
- 【PyQt】插入排序算法
# coding=utf-8 import sys from PyQt4.QtGui import * from PyQt4.QtCore import * class MainWindow(QMai ...
- Idea定位打开文件在左边工程中的文件路径
勾选掉Autoscoll from Source