题目链接:

http://codeforces.com/problemset/problem/242/E

E. XOR on Segment

time limit per test 4 seconds
memory 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 线段树的更多相关文章

  1. codeforces 242E. XOR on Segment 线段树

    题目链接 给n个数, 两种操作, 一种是求区间内的数的和, 一种是将区间内的数异或x. 异或x没有什么思路, 单个异或肯定超时, 区间异或也没有办法做....后来才知道可以按位建线段树, 这样建20棵 ...

  2. 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. 这题 ...

  3. XOR on segment(线段树区间异或更新)

    原题传送门 本题大意:给定n个数字和m个操作,操作共有两种,第一种是求解区间l到r上元素的和,第二种是将区间l到r的元素都异或一个x,作为某个位置的新值. 很容易想到线段树维护区间和,但是我们发现,在 ...

  4. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  5. luogu P2574 XOR的艺术 (线段树)

    luogu P2574 XOR的艺术 (线段树) 算是比较简单的线段树. 当区间修改时.\(1 xor 1 = 0,0 xor 1 = 1\)所以就是区间元素个数减去以前的\(1\)的个数就是现在\( ...

  6. codeforces 242E - XOR on Segment (线段树 按位数建树)

    E. XOR on Segment time limit per test 4 seconds memory limit per test 256 megabytes input standard i ...

  7. CodeForces 242E - XOR on Segment 二维线段树?

    今天练习赛的题....又是线段树的变换..拿到题我就敲了个点更新区间查询的..果断超时...然后想到了可以将每个数与合表示成不进位的二进制数..这样就可以区间进行更新了..比赛的时候写搓了..刚重写了 ...

  8. CodeForces 242E "XOR on Segment"(线段树)

    传送门 •题意 给你一个包含 n 个数的序列 a,定义序列上的两个操作: (1)$1,l,r\ :\ ans=\sum_{i=l}^{r}a_i$; (2)$2,l,r,x\ :\ \forall\ ...

  9. CodeForces 516C Drazil and Park 线段树

    原文链接http://www.cnblogs.com/zhouzhendong/p/8990745.html 题目传送门 - CodeForces 516C 题意 在一个环上,有$n$棵树. 给出每一 ...

随机推荐

  1. Win2008R2PHP5.4环境加载Zend模块

    1.需要2个文件 Zend Optimizer和Zend Guard Loade s 下载Zend Guard Loader包.(官方地址:http://www.zend.com/en/product ...

  2. C#中使用官方驱动操作MongoDB

    想要在C#中使用MongoDB,首先得要有个MongoDB支持的C#版的驱动.C#版的驱动有很多种,如官方提供的,samus. 实现思路大都类似.这里我们先用官方提供的mongo-csharp-dri ...

  3. .Net 内存泄露

    一.事件引起的内存泄露 1.不手动注销事件也不发生内存泄露的情况 我们经常会写EventHandler += AFunction; 如果没有手动注销这个Event handler类似:EventHan ...

  4. 多屏判断css改写

    function replaceBodyClass(){ for(var i in map){ if(map[i](width)){ document.body.className = documen ...

  5. Hadoop在win7下部署的问题

    问题: 为了测试方便所以在win7下部署了伪分布式hadoop运行环境,但是部署结束后在命令行运行hadoop命令创建一个用户文件目录时出现了一下情况: 系统找不到指定的批标签- make_comma ...

  6. Google -We’re Sorry....

    Author:KillerLegend From:http://www.cnblogs.com/killerlegend/p/3734840.html Date:2014.5.18 一大清早 一大早起 ...

  7. BAT命令介绍【转自Internet】

    一.简单批处理内部命令简介 1.Echo 命令 打开回显或关闭请求回显功能,或显示消息.如果没有任何参数,echo 命令将显示当前回显设置. 语法: echo [{on│off}] [message] ...

  8. C# 平时碰见的问题【2】

    问题1 修改命名空间后 .ashx 类型创建失败 [情景] 在调整前后台项目结构的时候,修改了默认命名空间(XXX.Admin 修改成XXX.Web),结果调试的时候发现XXX.Admin.Ajax. ...

  9. Python开发【第一篇】Python基础之生成器和迭代器

    生成器和迭代器 1.生成器 一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator):如果函数中包含yield语法,那这个函数就会变成生成器: def func(): yield 1 ...

  10. [terry笔记]IMPDP报错ORA-39083 Object type TYPE failed to create ORA-02304

    今天在使用impdp导入的时候(同一数据库中转换schema),遇到了 ORA-39083: Object type TYPE failed to create with error: ORA-023 ...