NOIP集训 P11071 「QMSOI R1」 Distorted Fate 题解
对本题的评价:有思维含量的线段树好题。曲子好听,曲绘好看,曲师人品好,谱子写得好,鸠好看
题解: P11071 「QMSOI R1」 Distorted Fate
给定一个长度为 \(n\) 的数组 \(A\),你需要完成以下 \(q\) 次操作。
1.1 l r x
将 \(A_i(l\le i\le r)\) 异或上 \(x\)。
2.2 l r
求:
\]
其中 \(\bigcup\) 表示按位或。
Input
第一行输入两个数 \(n\) 和 \(q\),代表数组长度和操作的次数。
第二行输入 \(n\) 个整数,第 \(i\) 个数代表 \(A_i\) 的值。
接下来 \(q\) 行,每行输入三个整数 \(opt,l,r\) 。
若 \(opt=1\) ,则再输入一个整数 \(x\) 表示将区间 \([l,r]\) 中 \(A_i\) 异或上 \(x\)。
若 \(opt=2\) ,则代表这是一次查询。
Output
对于每个查询,输出一行一个整数代表所求式子的值 \(\bmod \ 2^{30}\) 的结果。
Note
对于所有数据,满足 \(0\le a_i,x<2^{30},1\le l\le r\le n\) 。
空间限制 \(100MB\) 。
分析
很自然往拆位的思路去想。
因为空间限制卡的很死,所以不能直接在线做。
先把操作离线下来,每一位单独做。由于是前缀按位或,相当于对于 \([l,r]\) 的 \(0/1\) 序列,找到第一个出现的 \(1\) 的位置,其后包括它本身都会对答案有贡献。
这样就可以考虑线段树上每个节点维护两个值 \(pos_0\) 和 \(pos_1\) ,分别表示值域内第一次出现 \(0\) 和 \(1\) 的位置,建树时如果 \(A_i\) 当前处理的位置上为 \(1\) 就把 \(pos_1\) 赋成 \(i\), \(pos_0\) 赋成极大值;当前位置上为 \(0\) 就反过来。每次处理如果 \(x_i\) 这一位为 \(1\) 就可以直接把 \([l,r]\) 的 \(pos_0, pos_1\) 交换(等价于异或),用 \(tag_u\) 延迟下放标记即可。
每次在同一片内存空间上建树,每一位操作可以重复在这一棵线段树上进行。记得清空标记。
AC代码:
#include<bits/stdc++.h>
using namespace std;
inline int read() {
int f = 1, otto = 0;
char a = getchar();
while(!isdigit(a)) {
if(a == '-') f = -1;
a = getchar();
}
while(isdigit(a)) {
otto = (otto << 1) + (otto << 3) + (a ^ 48);
a = getchar();
}
return f * otto;
}
const int maxn = 2e5 + 10, mo = 1 << 30, inf = 1 << 30;
int bit, a[maxn], ans[maxn], pos0[maxn << 2], pos1[maxn << 2];
struct REQ{
int op, l, r, x;
}req[maxn];
bool tag[maxn << 2];
void upd(int u) {
pos0[u] = min(pos0[u << 1], pos0[u << 1 | 1]), pos1[u] = min(pos1[u << 1], pos1[u << 1 | 1]);
return;
}
void build(int u, int l, int r) {
if(l == r) {
if((a[l] >> bit) & 1) pos0[u] = inf, pos1[u] = l;
else pos0[u] = l, pos1[u] = inf;
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
return upd(u), void(0);
}
void pushdown(int u) {
if(!tag[u]) return;
swap(pos0[u << 1], pos1[u << 1]), swap(pos0[u << 1 | 1], pos1[u << 1 | 1]);
tag[u << 1] ^= 1, tag[u << 1 | 1] ^= 1;
tag[u] = 0; //记得清空tag
return;
}
void Do(int u, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) {
tag[u] ^= 1;
swap(pos0[u], pos1[u]);
return;
}
pushdown(u);
int mid = l + r >> 1;
if(ql <= mid) Do(u << 1, l, mid, ql, qr);
if(mid < qr) Do(u << 1 | 1, mid + 1, r, ql, qr);
return upd(u), void(0);
}
int ask(int u, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) return pos1[u];
pushdown(u);
int mid = l + r >> 1, ret = inf;
if(ql <= mid) ret = min(ret, ask(u << 1, l, mid, ql, qr));
if(mid < qr) ret = min(ret, ask(u << 1 | 1, mid + 1, r, ql, qr));
return ret;
}
int main() {
int n = read(), q = read();
for(int i = 1; i <= n; i++) a[i] = read();
for(int i = 1; i <= q; i++) {
req[i].op = read(), req[i].l = read(), req[i].r = read();
if(req[i].op == 1) req[i].x = read();
}
for(bit = 0; bit <= 30; bit++) {
memset(tag, 0, sizeof tag);
build(1, 1, n);
for(int i = 1; i <= q; i++) {
if(req[i].op == 1 && (req[i].x >> bit) & 1) Do(1, 1, n, req[i].l, req[i].r);
if(req[i].op == 2) {
int res = ask(1, 1, n, req[i].l, req[i].r);
if(res != inf) ans[i] = (ans[i] + 1ll * (req[i].r - res + 1) * (1 << bit) % mo) % mo;
}
}
}
for(int i = 1; i <= q; i++) {
if(req[i].op == 2) printf("%d\n", ans[i]);
}
return 0;
}
NOIP集训 P11071 「QMSOI R1」 Distorted Fate 题解的更多相关文章
- LuoguP7127 「RdOI R1」一次函数(function) 题解
Content 设 \(S_k\) 为直线 \(f(x)=kx+k-1\),直线 \(f(x)=(k+1)x+k\) 与 \(x\) 轴围成的三角形的面积.现在给出 \(t\) 组询问,每组询问给定一 ...
- 「POI2011 R1」Conspiracy
「POI2011 R1」Conspiracy 解题思路 : 问题转化为,将点集分成两部分,其中一部分恰好组成一个团,其中另一部分恰好组成一个独立集. 观察发现,如果求出了一个解,那么答案最多可以在这个 ...
- LOJ #2541. 「PKUWC 2018」猎人杀(容斥 , 期望dp , NTT优化)
题意 LOJ #2541. 「PKUWC 2018」猎人杀 题解 一道及其巧妙的题 , 参考了一下这位大佬的博客 ... 令 \(\displaystyle A = \sum_{i=1}^{n} w_ ...
- LOJ #2540. 「PKUWC 2018」随机算法(概率dp)
题意 LOJ #2540. 「PKUWC 2018」随机算法 题解 朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 ...
- Note -「动态 DP」学习笔记
目录 「CF 750E」New Year and Old Subsequence 「洛谷 P4719」「模板」"动态 DP" & 动态树分治 「洛谷 P6021」洪水 「S ...
- 「AHOI / HNOI2017」影魔
「AHOI / HNOI2017」影魔 题目描述 解决这类比较复杂的区间贡献问题关键在于找到计算的对象. 比如这道题,我们计算的对象就是区间中间的最大值. 对于点\(i\),我们找到左边第一个比他大的 ...
- 「GXOI / GZOI2019」简要题解
「GXOI / GZOI2019」简要题解 LOJ#3083. 「GXOI / GZOI2019」与或和 https://loj.ac/problem/3083 题意:求一个矩阵的所有子矩阵的与和 和 ...
- [LOJ 2022]「AHOI / HNOI2017」队长快跑
[LOJ 2022]「AHOI / HNOI2017」队长快跑 链接 链接 题解 不难看出,除了影响到起点和终点的射线以外,射线的角度没有意义,因为如果一定要从该射线的射出一侧过去,必然会撞到射线 因 ...
- 「国家集训队」小Z的袜子
「国家集训队」小Z的袜子 传送门 莫队板子题. 注意计算答案的时候,由于分子分母都要除以2,所以可以直接约掉,这样在开桶算的时候也方便一些. 参考代码: #include <algorithm& ...
- P7708「Wdsr-2.7」八云蓝自动机 Ⅰ
*X. P7708「Wdsr-2.7」八云蓝自动机 Ⅰ. 摘自 分治与根号数据结构学习笔记 第三部分 莫队 例题 X.. 一道莫队好题.私以为本题最有价值的地方在于对单点修改的转化以及对交换两个数的处 ...
随机推荐
- Irwin-Hall 分布/CF1477F 题解
Irwin-Hall 分布 对于 \(n\) 个均匀分布于 \([0,1]\) 的连续随机变量 \(X_1,X_2,\dots,X_n\),其和的随机变量 \(X\) 满足: \[P(X\le x)= ...
- SQL Server 2022新功能:将数据库备份到S3兼容的对象存储
SQL Server 2022新功能:将数据库备份到S3兼容的对象存储 本文介绍将S3兼容的对象存储用作数据库备份目标所需的概念.要求和组件. 数据库备份和恢复功能在概念上类似于使用SQL Serve ...
- Codeforces 232 B Table 题解 [ 蓝 ] [ 分组背包 ] [ 组合数学 ] [ 循环节 ]
Codeforces 232B Table. 蒟蒻模拟赛上场切的一道蓝,非常难以置信我竟然能做蓝题. 这题的数据范围初看还是比较坑的,\(10^{18}\) 的值域很容易让人往矩阵加速那方面想.实际上 ...
- TensorFlow函数 tf.argmax()
参数: input:输入数据 dimension:按某维度查找. dimension=0:按列查找: dimension=1:按行查找: 返回: 最大值的下标 import tensorflow.co ...
- VS2019 MSB6006 "CL.exe"已退出,错误代码 5
以下为我的解决过程: 因为我不是干C++的,而且我们内网不通外网,我当初来的时候装的vs2019全家桶,然后他们开发用的是vs2015,项目有用c++做图像处理的东西,我本地的vs2015没有C++模 ...
- 火爆的 幻兽帕鲁/Palworld 单机➕联机 电脑游戏 免费畅游
在广阔的世界中收集神奇的生物"帕鲁",派他们进行战斗.建造.做农活,工业生产等,这是一款支持多人游戏模式的全新开放世界生存制作游戏. ▼补丁主要内容 ・修复加载世界数据时,加载画面 ...
- 网线 - 568B接法
- C# 搭建一个 基于ISqlSugarClient 三层架构框架 涉及数据库仓储 然后中间又有业务逻辑层 案例
要在C#中搭建基于ISqlSugarClient的三层架构框架,你需要定义数据访问层(DAL).业务逻辑层(BLL)和表现层(UI).下面是一个完整的例子,涉及数据库仓储.业务逻辑层,以及依赖注入.这 ...
- 【Abaqus】*Solid Section定义复合材料
*SOLID SECTION 介绍 *solid section 用来定义单元的材料属性,材料方向等信息: solid (continuum) elements infinite elements a ...
- grpc unable to determine Go import path for
前言 在 proto 文件夹下执行如下命令: $ protoc --go_out=plugins=grpc:. *.proto 报错:无法确定Go导入路径 protoc-gen-go: unable ...