NC19429 红球进黑洞
题目
题目描述
在心理疏导室中有一种奇特的疏导工具,叫做红球。红球被提前分为了许多正方形小方格。
每当有人来找ATB做心理疏导时,ATB就会让他去先玩红球,然后通过红球小格方的高度来判断一个人的压力程度的高低。
具体地讲,ATB会让该人对于一个序列执行以下操作
- 区间求和,即输入 \(l,r\) ,输出 \(\sum_{i=l}^{r} x_i\)
- 区间异或,即输入 \(l,r,k\) ,对于\(l ≤ i ≤ r\) ,将 \(x_i\) 变为 \(x_i \oplus k\)
可是ATB天天算计那么多答案,已经对这份工作产生了厌烦,所以请你帮帮他,对于一组给定的数据,输出对应的答案
ATB会将你感谢到爆
输入描述
第一行两个整数 \(n\) 和 \(m\) ,表示数列长度和询问次数
第二行有 \(n\) 个整数,表示这个数列的初始数值
接下来有 \(m\) 行,形如 1 l r 或者 2 l r k
分别表示查询 \(\sum_{i=l}^{r} a_i\)
或者对于 \(l ≤ i ≤ r\) ,将 \(x_i\) 变为 \(x_i \oplus k\)
输出描述
对于每一个查询操作,输出查询的结果并换行
示例1
输入
10 10
8 5 8 9 3 9 8 3 3 6
2 1 4 1
1 2 6
2 9 10 8
1 1 7
2 4 7 8
2 8 8 6
2 2 3 0
1 1 2
2 9 10 4
1 2 3
输出
33
50
13
13
备注
数据范围
对于 \(30\%\) 的数据,保证 \(n, m, k≤ 10\)
对于另外 \(30\%\) 的数据,保证 \(n, m ≤ 50000, k ∈ \{0, 1\}\)
对于全部 \(100\%\) 的数据,保证 \(1 ≤ n,m ≤ 10^5, 0≤ a_i,k ≤ 10^5\)说明
\(a \oplus b\) 表示 \(a \text{ xor } b\)
题解
知识点:线段树,位运算。
显然我们无法对区间和作异或运算,这导致区间修改无法懒标记。
但是,我们可以尝试按位考虑,记录一个区间每一位的 \(1\) 有多少个,这样做也是可以复原区间和的。同时,区间异或就转化成每位 \(0,1\) 数量置换,这是可以使用懒标记的信息。
随后就是朴素的线段树区间查询、区间修改。
时间复杂度 \(O((n+m)) \log n\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct T {
int len;
ll sum;
array<int, 31> bits;
static T e() { return { 0,0,{} }; }
friend T operator+(const T &a, const T &b) {
T x = T::e();
x.len = a.len + b.len;
x.sum = a.sum + b.sum;
for (int i = 0;i <= 30;i++) x.bits[i] = a.bits[i] + b.bits[i];
return x;
}
};
struct F {
int oplus;
static F e() { return { 0 }; }
T operator()(const T &x) {
T fx = T::e();
fx.len = x.len;
for (int i = 0;i <= 30;i++) fx.bits[i] = oplus >> i & 1 ? x.len - x.bits[i] : x.bits[i];
for (int i = 0;i <= 30;i++) fx.sum += fx.bits[i] * (1LL << i);
return fx;
}
F operator()(const F &f) { return { f.oplus ^ oplus }; }
};
template <class T, class F>
class SegmentTreeLazy {
int n;
vector<T> node;
vector<F> lazy;
void push_down(int rt) {
node[rt << 1] = lazy[rt](node[rt << 1]);
lazy[rt << 1] = lazy[rt](lazy[rt << 1]);
node[rt << 1 | 1] = lazy[rt](node[rt << 1 | 1]);
lazy[rt << 1 | 1] = lazy[rt](lazy[rt << 1 | 1]);
lazy[rt] = F::e();
}
void update(int rt, int l, int r, int x, int y, F f) {
if (r < x || y < l) return;
if (x <= l && r <= y) return node[rt] = f(node[rt]), lazy[rt] = f(lazy[rt]), void();
push_down(rt);
int mid = l + r >> 1;
update(rt << 1, l, mid, x, y, f);
update(rt << 1 | 1, mid + 1, r, x, y, f);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
}
T query(int rt, int l, int r, int x, int y) {
if (r < x || y < l) return T::e();
if (x <= l && r <= y) return node[rt];
push_down(rt);
int mid = l + r >> 1;
return query(rt << 1, l, mid, x, y) + query(rt << 1 | 1, mid + 1, r, x, y);
}
public:
SegmentTreeLazy(int _n = 0) { init(_n); }
SegmentTreeLazy(const vector<T> &src) { init(src); }
void init(int _n) {
n = _n;
node.assign(n << 2, T::e());
lazy.assign(n << 2, F::e());
}
void init(const vector<T> &src) {
assert(src.size() >= 2);
init(src.size() - 1);
function<void(int, int, int)> build = [&](int rt, int l, int r) {
if (l == r) return node[rt] = src[l], void();
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
node[rt] = node[rt << 1] + node[rt << 1 | 1];
};
build(1, 1, n);
}
void update(int x, int y, F f) { update(1, 1, n, x, y, f); }
T query(int x, int y) { return query(1, 1, n, x, y); }
};
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
vector<T> a(n + 1);
for (int i = 1;i <= n;i++) {
int x;
cin >> x;
a[i] = T::e();
a[i].len = 1;
a[i].sum = x;
for (int j = 0;j <= 30;j++) a[i].bits[j] = x >> j & 1;
}
SegmentTreeLazy<T, F> sgt(a);
while (m--) {
int op, l, r;
cin >> op >> l >> r;
if (op == 1) cout << sgt.query(l, r).sum << '\n';
else {
int x;
cin >> x;
sgt.update(l, r, { x });
}
}
return 0;
}
NC19429 红球进黑洞的更多相关文章
- 试题系列四(袋中有6红球 3黄球 3绿球,从中取6个球,求所有拿到球的颜色的可能 c(12,6))
1.袋中有6红球 3黄球 3绿球,从中取6个球,求所有拿到球的颜色的可能 c(12,6) #include<stdio.h> int main(int argc, char** argv) ...
- cdoj 24 8球胜负(eight) 水题
8球胜负(eight) Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/24 ...
- HDOJ/HDU 2537 8球胜负(水题.简单的判断)
Problem Description 8球是一种台球竞赛的规则.台面上有7个红球.7个黄球以及一个黑球,当然还有一个白球.对于本题,我们使用如下的简化规则:红.黄两名选手轮流用白球击打各自颜色的球, ...
- HDU2537:8球胜负
Problem Description 8球是一种台球竞赛的规则.台面上有7个红球.7个黄球以及一个黑球,当然还有一个白球.对于本题,我们使用如下的简化规则:红.黄两名选手轮流用白球击打各自颜色的球, ...
- 美式九球比赛规则 (Nine-ball)
九球比赛规则 (Nine-ball) 九球比赛规则 一.器材: 1.台面规格: a.内沿长254厘米. b.内沿宽127厘米. c.高80厘米. d.角袋口内沿最近距离为10.5厘米(±1毫米),腰袋 ...
- HDUOJ--8球胜负
8球胜负 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- CDOJ_24 八球胜负
8球是一种台球竞赛的规则.台面上有7个红球.7个黄球以及一个黑球,当然还有一个白球.对于本题,我们使用如下的简化规则:红.黄两名选手轮 流用白球击打各自颜色的球,如果将该颜色的7个球全部打进,则这名选 ...
- 黑洞有毛 or 黑洞无毛:4星|《环球科学》2019年03月号
<环球科学>2019年03月号 高水平的科普杂志.本期我感兴趣的话题有: 1:65岁以上老年人是转发假新闻的主力: 2:人的面孔特征可以通过50个维度来定义: 3:华裔科学家发现人脑颞叶中 ...
- 把大象装进冰箱的N种方法
作者:折剑头链接:https://www.zhihu.com/question/49214119/answer/115728034来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- 蓝桥杯 C/C++参考题目 取球概率(数学题,概率)
口袋中有5只红球,4只白球.随机从口袋中取出3个球,则取出1个红球2个白球的概率是多大?类似这样的数学问题,在计算的时候往往十分复杂.但如果通过计算机模拟这个过程,比如进行100000次取球模拟,统计 ...
随机推荐
- Blazor的技术优点
Blazor是一种使用.NET和C#构建客户端Web应用程序的新兴技术.它允许开发者在浏览器中直接运行.NET代码,而无需依赖JavaScript.Blazor的技术优点主要表现在以下几个方面: 单一 ...
- 使用React简短代码动态生成栅格布局
使用React简短代码动态生成栅格布局 作为 TerminalMACS 的一个子进程模块 - React Web管理端,使用Ant Design Pro作为框架. 本文应用到的知识 1.样式文件les ...
- 如何部署两个JMS网关,形成双机热备
大家使用JMS的过程中,可能会留意到,不管是微服务在注册时,还是RemoteClient构造时,所指向的网关都是一个NetAddress数组,之所以网关地址是多个,而不是一个,那是因为网关是一个双击热 ...
- [转帖]【split】Linux上用 split实现大文件的拆分和合并
https://www.jianshu.com/p/87748b8563a9 有没有遇到某些网站上传复件时,单个文件有大小限制,导致上传失败呢?当然你可以采用更高的压缩率重新生成压缩包来解决,但如果还 ...
- ext4 磁盘扩容
目录 ext4文件系统磁盘扩容 目标 途径 操作步骤 改变前的现状 操作和改变后的状态 ext4文件系统磁盘扩容 一个磁盘有多个分区,分别创建了物理卷.卷组.逻辑卷.通过虚拟机软件对虚拟机的磁盘/de ...
- [转帖]Linux实用技巧——find查找指定时间内修改过的文件或目录
https://cloud.tencent.com/developer/article/1694949 解决方案 例:查找出五分钟内修改过的文件 [root@mobius ~]$ find ./* - ...
- [转帖]Spring Cloud Alibaba Nacos 注册中心使用教程
一. 什么是Nacos Nacos是一个更易于构建云原生应用的动态服务发现(Nacos Discovery ).服务配置(Nacos Config)和服务管理平台,集注册中心+配置中心+服务管理于一身 ...
- 400G 光模块的价格
400G 光模块的价格 令人惊叹... https://www.fs.com/cn/c/40g-100g-transceivers-889?pro_type=&sortby=priced&a ...
- 大数据面试题集锦-Hadoop面试题(一)
目录 1.集群的最主要瓶颈 2.Hadoop运行模式 3.Hadoop生态圈的组件并做简要描述 4.解释"hadoop"和"hadoop 生态系统"两个概念 5 ...
- Jupyter Notebook支持Go
在执行下列命令之前,请确保你已经安装了Go和Jupyter. gophernotes是针对Jupyter和nteract的Go内核,它可以让你在基于浏览器的笔记本或桌面app上交互式地使用Go.下面介 ...