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次取球模拟,统计 ...
随机推荐
- 打 multi-fidelity RL 旗号,但是幼稚监督学习 + 迁移学习
文章名称:Multi-fidelity reinforcement learning framework for shape optimization 链接:https://www.sciencedi ...
- springboot - 解决使用pagehelper 报 SQL语句异常
原因: mapper.xml 中的sql加上了分号. <select id="search" resultType="***.Table"> sel ...
- makefile文件详解
1. make 编译:将源代码文件翻译成处理器可执行的二进制文件的过程,这个过程的时间区间称为编译时 构建:指定多个编译过程的先后顺序 make命令是常用的构建工具,诞生于1977年,主要用于C/C+ ...
- K8s集群CoreDNS监控告警最佳实践
本文分享自华为云社区<K8s集群CoreDNS监控告警最佳实践>,作者:可以交个朋友. 一 背景 coreDNS作为K8s集群中的关键组成部分.主要负责k8s集群中的服务发现,域名解析等功 ...
- [转帖]OS、PFS、DFS 有啥区别?一文搞懂 6 大临床试验终点
https://oncol.dxy.cn/article/670607 说到肿瘤临床研究,就不得不说临床试验终点(End Point),比如大家熟知的 OS.PFS.ORR 还有 DFS.TTP.TT ...
- [转帖]Oracle数据库中ITL详解
首先说明这篇文章是转载的,原文地址:http://blog.sina.com.cn/s/blog_616b428f0100lwvq.html 1.什么是ITL ITL(Interested Trans ...
- [转帖]「Linux性能调优」磁盘I/O队列调度策略
https://zhuanlan.zhihu.com/p/450329513 傻瓜化说明 简单地说,对于磁盘I/O,Linux提供了cfq, deadline和noop三种调度策略 cfq: 这个名字 ...
- [转帖]NOHZ = ON如何影响Linux内核中的do_timer()?
https://www.jb51.cc/faq/897483.html 如何解决NOHZ = ON如何影响Linux内核中的do_timer()?? 首先,让我们了解什么是tickless kerne ...
- [转帖]CPU的制造和概念
https://plantegg.github.io/2021/06/01/CPU%E7%9A%84%E5%88%B6%E9%80%A0%E5%92%8C%E6%A6%82%E5%BF%B5/ 为了让 ...
- RabbitMQ 测试环境的简单创建于使用 permission vhost 以及 权限简单设置
之前用docker运行起来 rabbitmq的容器了 但是今天发现有问题. 简单沟通了下 需要进行处理. 方法主要是如下 1. 运行容器: docker run --name rabbitmq -ti ...