You've got an array a, consisting of n integers a1, a2, ..., an. You are allowed to perform two operations on this array:
- Calculate the sum of current array elements on the segment [l, r], that is, count value al + al + 1 + ... + ar.
- Apply the xor operation with a given number x to each array element on the segment [l, r], that is, execute
. This operation changes exactly r - l + 1 array elements.
Expression means applying bitwise xor operation to numbers x and y. The given operation exists in all modern programming languages, for example in language C++ and Java it is marked as "^", in Pascal — as "xor".
You've got a list of m operations of the indicated type. Your task is to perform all given operations, for each sum query you should print the result you get.
The first line contains integer n (1 ≤ n ≤ 105) — the size of the array. The second line contains space-separated integers a1, a2, ..., an(0 ≤ ai ≤ 106) — the original array.
The third line contains integer m (1 ≤ m ≤ 5·104) — the number of operations with the array. The i-th of the following m lines first contains an integer ti (1 ≤ ti ≤ 2) — the type of the i-th query. If ti = 1, then this is the query of the sum, if ti = 2, then this is the query to change array elements. If the i-th operation is of type 1, then next follow two integers li, ri (1 ≤ li ≤ ri ≤ n). If the i-th operation is of type 2, then next follow three integers li, ri, xi (1 ≤ li ≤ ri ≤ n, 1 ≤ xi ≤ 106). The numbers on the lines are separated by single spaces.
For each query of type 1 print in a single line the sum of numbers on the given segment. Print the answers to the queries in the order in which the queries go in the input.
Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams, or the %I64dspecifier.
5 4 10 3 13 7 8 1 2 4 2 1 3 3 1 2 4 1 3 3 2 2 5 5 1 1 5 2 1 2 10 1 2 3
26 22 0 34 11
6 4 7 4 0 7 3 5 2 2 3 8 1 1 5 2 3 5 1 2 4 5 6 1 2 3
38 28
题意:
给出 N(1 ~ 10 ^ 5),代表有 N 个数,后给出这 N 个数 ai (0 ~ 10 ^ 6)。有两个操作,1 操作是求出 a 到 b 的区间和,2 操作是对 a 到 b 区间的数 异或 ans。每次 1 操作的时候输出结果。
思路:
线段树 + 延迟标记。将每个数都拆成 20 位二进制来统计,建成 20 颗线段树,异或的时候对区间操作所以要用延迟标记。
1 求和操作就是将每位数都拆成 20 位二进制数,后统计每位有多少个 1,然后乘以 2 ^ i,再求和得出的这个数就是求和操作的结果;
2 异或操作,当异或 0 的时候不改变状态,若异或 1 则对区间内的 0 和 1 个数倒转,因为 0 xor 1 = 1,1 xor 1 = 0。
注意改变状态的时候要 flag = 1 - flag,当 flag 是 1 的时候说明要改变儿子的值,当是 0 的时候说明不用改变,若直接 flag = 1 的话,则一直为改变状态;而 flag = 1 - flag,说明当前为 1 的话,flag 会变成 0 说明不用改变,当前为 0 的话,flag 会变成 1,说明需要改变。
AC:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int MAX = 100005; int n, dim, s, e, cha; int num[MAX]; int tree[25][MAX * 5], flag[25][MAX * 5]; ll res; void Build(int k, int fro, int to) { int mid = (fro + to) / 2; flag[dim][k] = 0; if (fro == to) { tree[dim][k] = (num[fro] >> dim) & 1; return; } Build(k * 2, fro, mid); Build(k * 2 + 1, mid + 1, to); tree[dim][k] = tree[dim][2 * k] + tree[dim][2 * k + 1]; } void Sum(int k, int fro, int to) { int mid = (fro + to) / 2; if (to < s || fro > e) return; if (fro >= s && to <= e) { res += tree[dim][k]; return; } if (flag[dim][k]) { flag[dim][k] = 0; flag[dim][k * 2] = 1 - flag[dim][k * 2]; flag[dim][k * 2 + 1] = 1 - flag[dim][k * 2 + 1]; tree[dim][k * 2] = mid - fro + 1 - tree[dim][k * 2]; tree[dim][k * 2 + 1] = to - mid - tree[dim][k * 2 + 1]; } Sum(k * 2, fro, mid); Sum(k * 2 + 1, mid + 1, to); } void Xor(int k, int fro, int to) { int mid = (fro + to) / 2; if (s > to || e < fro) return; if (s <= fro && e >= to) { flag[dim][k] = 1 - flag[dim][k]; tree[dim][k] = to - fro + 1 - tree[dim][k]; return; } if (flag[dim][k]) { flag[dim][k] = 0; flag[dim][k * 2] = 1 - flag[dim][k * 2]; flag[dim][k * 2 + 1] = 1 - flag[dim][k * 2 + 1]; tree[dim][k * 2] = mid - fro + 1 - tree[dim][k * 2]; tree[dim][k * 2 + 1] = to - mid - tree[dim][k * 2 + 1]; } Xor(k * 2, fro, mid); Xor(k * 2 + 1, mid + 1, to); tree[dim][k] = tree[dim][k * 2] + tree[dim][k * 2 + 1]; } int main() { scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%d", &num[i]); for (dim = 0; dim <= 20; ++dim) Build(1, 1, n); int m; scanf("%d", &m); while (m--) { int way; scanf("%d", &way); if (way == 1) { scanf("%d%d", &s, &e); ll sum = 0; for (dim = 0; dim < 20; ++dim) { res = 0; Sum(1, 1, n); sum += res * (1 << dim); } printf("%I64d\n", sum); } else { scanf("%d%d%d", &s, &e, &cha); for (dim = 0; dim < 20; ++dim) if (cha & (1 << dim)) Xor(1, 1, n); } } return 0; }
相关推荐
XOR on segment问题可以通过线段树在二进制级别上进行处理。对每一位建立独立的线段树,维护区间异或和以及区间翻转(0变1,1变0)的状态,从而解决区间异或和的查询与更新。 Queries问题则要求支持单点修改和子...
本文将详细解析"XOR.rar_52xor25计算结果_XOR_XOR 8bit 算法_异或运算"所涉及的知识点。 首先,XOR(异或)运算是一种二元逻辑运算,它有两个输入和一个输出。如果两个输入位相同,输出为0;如果两个输入位不同,...
VHDL例程源码 xor2VHDL例程源码 xor2VHDL例程源码 xor2VHDL例程源码 xor2VHDL例程源码 xor2VHDL例程源码 xor2VHDL例程源码 xor2VHDL例程源码 xor2VHDL例程源码 xor2VHDL例程源码 xor2VHDL例程源码 xor2VHDL例程源码 ...
### Kademlia:基于XOR度量的对等信息系统的深度解析 #### 摘要与背景 本文探讨了一种名为Kademlia的对等(Peer-to-Peer, P2P)系统,该系统旨在提供一种可靠且高效的数据存储与检索机制。Kademlia的核心优势在于...
《XOR加密技术详解及其在"xor加密.exe"中的应用》 XOR(异或)加密是一种简单而有效的加密手段,常被用于程序保护、数据隐藏等领域。在信息技术中,XOR运算因其特性——相同的输入产生0,不同的输入产生1,而被广泛...
这个名为“XOR.zip”的压缩包包含了一个异或校验工具,该工具能够帮助用户快速计算16进制字符串的异或校验码。这里我们将深入探讨异或运算以及如何使用它来进行校验。 异或(XOR,exclusive OR)是一种逻辑运算符,...
在IT行业中,XOR(异或)操作是一种基本的位操作,它在计算机科学和编程中扮演着重要的角色。在“xor文件.zip”这个压缩包中,我们可以推测它可能包含了一些与XOR操作相关的文件或者教程。下面我们将深入探讨XOR操作...
%%使用fisher判别给XOR问题分类 使用fisher判别给XOR问题分类
XOR(异或)加密是一种简单的加密方法,广泛应用于数据隐藏和初步的数据保护。它的基本原理是:将明文与一个密钥进行异或操作,得到密文;解密时,再将密文与相同的密钥进行异或,即可恢复原文。在本案例中,我们有...
本文将详细介绍三种常见的加密算法:AES、DES和XOR,并在VB.NET环境下,结合VS2013开发工具,探讨它们的实现方法。 首先,我们来看AES(Advanced Encryption Standard),即高级加密标准。AES是目前最广泛使用的...
在IT领域,XOR(异或)操作是一种基本的逻辑运算,它在计算机科学和编程中扮演着重要的角色。本文将深入探讨XOR的概念、在C++中的应用以及与BP神经网络(BackPropagation Neural Network)的关联。 XOR,全称是...
此外,由于异或运算的交换律(A XOR B = B XOR A)和结合律(A XOR (B XOR C) = (A XOR B) XOR C),这款工具也可能包含一些高级功能,比如批量异或多个数值,或者保存/加载异或历史记录,方便用户进行多次异或操作...
标题中的“Xor.rar_SVM XOR matlab_XOR_xor by matalb”暗示了这是一个关于使用支持向量机(SVM)和Matlab解决异或(XOR)问题的项目。在机器学习领域,异或问题因其非线性特性而被视为一个经典的教学案例,通常用于...
为了确保数据的完整性和准确无误,XOR校验和字符转换工具集应运而生,它提供了一套完整的解决方案,用以检测数据是否在传输或存储过程中出现错误。 XOR校验和字符转换工具集的核心功能是XOR校验。XOR校验是一种通过...
在IT行业中,XOR(异或)是一种基本的逻辑运算符,广泛应用于各种算法和程序设计中。XOR,即“Exclusive OR”,它的特点是当两个输入位不同时,结果为1;而当两个输入位相同时,结果为0。这个特性使得XOR在数据处理...
XOR(异或)是一种基础的逻辑运算,被广泛用于各种加密算法中,包括XOR 256。在本例中,我们将探讨如何在VC++环境下利用XOR 256加密算法对文本或文件进行加解密。 XOR 256加密算法的核心在于使用一个256位的密钥与...
标签"xor matlab_xor neural_xor_matlab zip"进一步确认了这个主题,其中"xor"指的是异或操作,"matlab_xor"表明代码是用MATLAB编写的,"neural_xor_matlab"强调是用MATLAB实现的神经网络来解决XOR问题,"zip"则表示...
标题中的“nns xor.rar_XOR_XOR c++_bp xor”表明这是一个关于神经网络(nns)解决异或(XOR)问题的项目,使用了C++编程语言,并且采用了反向传播(BP)算法。这个压缩包可能包含相关的源代码、数据集和文档,如...
这种特性使得XOR在加密中发挥了重要作用,因为通过两次XOR相同的密钥,原始数据可以被恢复,这就是XOR加密的基本原理。 在Delphi编程环境中,我们可以创建两个程序,一个用于加密(Crypt.dpr和Crypt.exe),另一个...
XOR 效验 算KEY程序 非常好用的