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$棵树. 给出每一 ...
随机推荐
- [leetcode]_Path Sum I && II
都是考查DFS.经典回溯算法,问题在于我对该类型的代码不熟悉,目前以参考别人的代码,然后加上自己的实现为主,通过类似的题目加强理解. 一.给定一棵二叉树,判断是否存在从root到leaf的路径和等于给 ...
- 在SQL中取出字符串中数字部分或在SQL中取出字符部分
在SQL中取出字符串中数字部分或在SQL中取出字符部分 编写人:CC阿爸 2013-10-18 近来在开发一个项目时,一包含数字的字符串,需要取出中间的数字部分进行排序.经过baidu搜索.并结合自己 ...
- luigi学习3-使用luigid
--local-scheduler的方式只适用于开发调试阶段,当你真正要把程序部署到一个产品时,我们推荐使用luigid服务. 使用luigid服务不但能提供锁服务(防止一个任务被多个进程重复执行), ...
- 360提供的SQL防注入
<?php class sqlsafe { private $getfilter = "'|(and|or)\\b.+?(>|<|=|in|like)|\\/\\*.+?\ ...
- jquery中的mouseenter实现理解
说在前面:首先说一下两者之间的区别,假设当前元素为element,mouseover事件具有冒泡特性,也就是说无论鼠标是从别的元素移动到element或者是从element的子元素移动到element ...
- Java排序
给出10个数,使用某种排序方法,按照从小到大的顺序输出个个数. 根据要求,首先得给出这10个数,这里的算法需要一个循环,数据结构需要一个长度为10的整型数组.首先用BufferedReader in= ...
- 带有×的EditText
代码: EditTextWithDel.java(直接复制): package com.sunday.customs; import com.example.customs.R; import and ...
- Laravel 5 基础(十一)- Eloquent 关系
一个用户可能有多个文章,一个文章是某个用户书写的,这就是关系.同样文章中可能包含多个 TAG,而一个 TAG 可能关联多个文章. 在项目中,我们已经有了 User.php,也就是用户模型,查看一下,相 ...
- DevExpress 关于 GridView 表格编辑中 点击其他按钮里导致 值未取到处理
只需要给添加以下代码 在执行其他按钮前调 用一下 就可以了:主要是用来关闭编辑以及更新当前行编辑内容 this.gridControl1.FocusedView.CloseEditor(); this ...
- Vim,一个开放源代码的文本编辑器(转)
Vim,http://linux.21ds.net/2002/03/13/0268dc26fd9c725c23dae68d797935f3/ 作者:Bram Moolenaar 翻译:slimzhao ...