codeforces 22E XOR on Segment 线段树
题目链接:
http://codeforces.com/problemset/problem/242/E
E. XOR on Segment
time limit per test 4 secondsmemory limit per test 256 megabytes
#### 问题描述
> 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 %I64d specifier.
#### 样例
> **sample input**
> 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
>
> **sample output**
> 26
> 22
> 0
> 34
> 11
## 题意
> 给你n个数,q个操作:
> 查询:返回l到r的和
> 更新:l到r的每个数都异或上x。
题解
对没个数字按二进制展开,存放在20颗线段树里面。
然后就转化成了一个经典的区间更新区间查询的线段树问题了。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#define lson (o<<1)
#define rson ((o<<1)|1)
#define M (l+(r-l)/2)
using namespace std;
const int maxn=1e5+10;
const int maxm=22;
typedef __int64 LL;
int n;
int sumv[maxm][maxn<<2];
int setv[maxn<<2];
void maintain(int o) {
	for(int i=0; i<maxm; i++) {
		sumv[i][o]=sumv[i][lson]+sumv[i][rson];
	}
}
void pushdown(int o,int l,int r) {
	for(int i=0; i<maxm; i++) {
		if(setv[o]&(1<<i)) {
			sumv[i][lson]=M-l+1-sumv[i][lson];
			sumv[i][rson]=r-M-sumv[i][rson];
		}
	}
	setv[lson]^=setv[o];
	setv[rson]^=setv[o];
	setv[o]=0;
}
void build(int o,int l,int r) {
	if(l==r) {
		int x;
		scanf("%d",&x);
		for(int i=0; i<maxm; i++) {
			if(x&(1<<i)) sumv[i][o]=1;
			else sumv[i][o]=0;
		}
	} else {
		build(lson,l,M);
		build(rson,M+1,r);
		maintain(o);
	}
}
int ql,qr,_v;
void update(int o,int l,int r) {
	if(ql<=l&&r<=qr) {
		for(int i=0; i<maxm; i++) {
			if(_v&(1<<i)) {
				sumv[i][o]=r-l+1-sumv[i][o];
			}
		}
		setv[o]^=_v;
	} else {
		pushdown(o,l,r);
		if(ql<=M) update(lson,l,M);
		if(qr>M) update(rson,M+1,r);
		maintain(o);
	}
}
LL _sum;
void query(int o,int l,int r){
	if(ql<=l&&r<=qr){
		for(int i=0;i<maxm;i++){
			_sum+=sumv[i][o]*((1LL)<<i);
		}
	}else{
		pushdown(o,l,r);
		if(ql<=M) query(lson,l,M);
		if(qr>M) query(rson,M+1,r);
		maintain(o);
	}
}
int main() {
	scanf("%d",&n);
	build(1,1,n);
	int q;
	scanf("%d",&q);
	while(q--) {
		int cmd;
		scanf("%d",&cmd);
		scanf("%d%d",&ql,&qr);
		if(cmd==1) {
			_sum=0;
			query(1,1,n);
			printf("%I64d\n",_sum);
		} else {
			scanf("%d",&_v);
			update(1,1,n);
		}
	}
	return 0;
}
Notes
其实和XOR有关的题目大部分都是套路!!!!二进制展开,你会发现一个新的世界!!!!
codeforces 22E XOR on Segment 线段树的更多相关文章
- codeforces 242E. XOR on Segment  线段树
		
题目链接 给n个数, 两种操作, 一种是求区间内的数的和, 一种是将区间内的数异或x. 异或x没有什么思路, 单个异或肯定超时, 区间异或也没有办法做....后来才知道可以按位建线段树, 这样建20棵 ...
 - Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)
		
题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题 ...
 - XOR on segment(线段树区间异或更新)
		
原题传送门 本题大意:给定n个数字和m个操作,操作共有两种,第一种是求解区间l到r上元素的和,第二种是将区间l到r的元素都异或一个x,作为某个位置的新值. 很容易想到线段树维护区间和,但是我们发现,在 ...
 - codeforces Good bye 2016 E 线段树维护dp区间合并
		
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
 - luogu P2574 XOR的艺术 (线段树)
		
luogu P2574 XOR的艺术 (线段树) 算是比较简单的线段树. 当区间修改时.\(1 xor 1 = 0,0 xor 1 = 1\)所以就是区间元素个数减去以前的\(1\)的个数就是现在\( ...
 - codeforces 242E - XOR on Segment (线段树  按位数建树)
		
E. XOR on Segment time limit per test 4 seconds memory limit per test 256 megabytes input standard i ...
 - CodeForces 242E - XOR on Segment 二维线段树?
		
今天练习赛的题....又是线段树的变换..拿到题我就敲了个点更新区间查询的..果断超时...然后想到了可以将每个数与合表示成不进位的二进制数..这样就可以区间进行更新了..比赛的时候写搓了..刚重写了 ...
 - CodeForces 242E "XOR on Segment"(线段树)
		
传送门 •题意 给你一个包含 n 个数的序列 a,定义序列上的两个操作: (1)$1,l,r\ :\ ans=\sum_{i=l}^{r}a_i$; (2)$2,l,r,x\ :\ \forall\ ...
 - CodeForces 516C Drazil and Park 线段树
		
原文链接http://www.cnblogs.com/zhouzhendong/p/8990745.html 题目传送门 - CodeForces 516C 题意 在一个环上,有$n$棵树. 给出每一 ...
 
随机推荐
- linux下最大文件数
			
系统级:系统级设置对所有用户有效.可通过两种方式查看系统最大文件限制1 cat /proc/sys/fs/file-max 2 sysctl -a 查看结果中fs.file-max这项的配置数量如果需 ...
 - varnish状态引擎1
			
vcl: state engine:各引擎之间存一定程度上的相关性:前一个engine如果可以有多种下游engine,则上游engine需要用return指明 要转移的下游engine vcl_rec ...
 - mac brew install redis
			
在mac 下安装redis 执行brew install redis ==> Downloading http://download.redis.io/releases/redis-2.8.19 ...
 - Ueditor图片缩放的设置
			
最近在用Ueditor,功能绝逼强大,不过也有遗憾的地方,上传图片的时候自动缩放的小了,想要图片按宽度整体等比缩放,找了好久,研究了下,终于找到解决方法了. 先改前台的的dialogs/image/i ...
 - js中关于prototype学习(2015年1月5号晚)
			
prototype在js中为原型,只要是对象都有原型,最高原型为Object. 函数作为一特殊的对象,下面探讨prototype(原型)和function(函数)之间的关系. function A ( ...
 - Linux操作系统常用命令
			
http://www.cnblogs.com/huangzelin/p/5617611.html http://www.cnblogs.com/liumt/p/6117168.html
 - [.ashx檔?泛型处理程序?]基础入门#5....ADO.NET 与 将DB里面的二进制图片还原 (范例下载 & 大型控件的ImageField)
			
[.ashx檔?泛型处理程序?]基础入门#5....ADO.NET 与 将DB里面的二进制图片还原 (范例下载 & 大型控件的ImageField) http://www.dotblogs.c ...
 - pandas聚合和分组运算——GroupBy技术(1)
			
数据聚合与分组运算——GroupBy技术(1),有需要的朋友可以参考下. pandas提供了一个灵活高效的groupby功能,它使你能以一种自然的方式对数据集进行切片.切块.摘要等操作.根据一个或多个 ...
 - [terry笔记]Oracle数据泵-schema导入导出
			
数据泵是10g推出的功能,个人倒数据比较喜欢用数据泵. 其导入的时候利用remap参数很方便转换表空间以及schema,并且可以忽略服务端与客户端字符集问题(exp/imp需要排查字符集). 数据泵也 ...
 - 实战MySQL集群,试用CentOS 6下的MariaDB-Galera集成版
			
说起mysql的集群估计很多人会首先想起mysql自带的replication或者mysql-mmm.mysql-mmm其实也是基于mysql自带的replication的,不过封装的更好用一些,但是 ...