题目链接:

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. 多次绑定DataGridView的DataSource会报错 NullReferenceExcepti

    最近做了一个winform的项目,数据绑定在datagridview中,datagridview中的数据需要删除,分页,更新等之类的操作,所以就涉及到了datagridview的重新绑定问题,而且这些 ...

  2. Winform下WebBrowser 编辑模式 监听键盘按键事件

    最近使用 WebBrowser 做了个富文本编辑器(其实网上有很多很多).例如下面这个玩意(不要在意界面神马的) WebBrowser在编辑模式下可以有一些HTML标签的功能,改变字体大小颜色等等等. ...

  3. phpcms v9 源码解析-1 index.php

    这个是phpcms V9 的入口文件index.php. V9程序的执行绝大多数是从这个文件开始的,但不绝对,在项目下面的api.php和plugin.php是另外的入口文件,这里我们先不做深究. 在 ...

  4. Nginx Location匹配举例

    1.location / {       if (!-f $request_filename){              rewrite ^/(.+)$ /uri.php last;      }} ...

  5. Laravel 5 基础(十一)- 子视图和表单复用

    我们需要处理编辑文章的问题.当然我们可以手工添加新的路由,就像这样: Route::get('/articles/{id}/edit', 'ArticleController@edit'); 让我们在 ...

  6. PHP错误处理

    错误的分类: 1.语法错误     2.运行时错误 3.逻辑错误 调试方法:1.注释法 2.输出法 error_reporting(E_ALL & ~E_NOTICE & ~E_WAR ...

  7. 关于js中this的疑问

    学习bootstrap.js源码中被js里边的this绕的有点晕 /* ================================================================ ...

  8. spyder常用快捷键

    Ctrl + 1: 注释/反注释 Ctrl + 4/5: 块注释/块反注释 Ctrl + L: 跳转到行号 Tab/Shift + Tab: 代码缩进/反缩进 Ctrl +I:显示帮助

  9. SQLAlchemy连接数据库并在django admin显示

    SQLAlchemy 0.7     postgersql  9.0 SQLAlchemy连接数据库有两种方法,一种是classic,一种是modern 1,modern方法 from sqlalch ...

  10. Rails学习:create操作 局部模板

    学习Ruby on Rails实战真经 里面说rails4使用了strong parameters, 所以代码这么写:注意不是Event.new(params[:event])了,而是参数是函数返回值 ...