题目链接:

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. c#使用NPOI导出Excel及往Excel里追加记录

    最近在做一个打印发票的程序,要求保存打印记录,所以用到了NPOI往Excel里导入数据,但是遇到了一些问题没法解决,最后看了别人的Java程序后才明白.下面只是说明几个问题,而不是怎样使用NPOI 问 ...

  2. [leetcode]_Unique Paths

    题目:有一个m * n 的方格,如下图,一个小robot希望从左上角走到右下角,共有多少种不同的路线走法. 思路: 我的错误思路:全排列,从(0,0)走到(m - 1,n - 1)共需要往下走m-1步 ...

  3. ES6还是ES2015?

    遇到了一个困惑   原来称作es6的现在突然变成es2015 了 原因是这个事ecma-262 的第六次变更,所有以前按照惯例称为es6. 但是为了更小版本频繁发布,现在 标准叫法是:  esmasc ...

  4. 一个特别不错的jQuery快捷键插件:js-hotkeys

    这其实不是什么新技术,这个插件在很早前就已经发布了,之前有项目用到,所以分享出来添加方式的例子 jQuery.hotkeys.add('esc',function (){ //执行函数 }); jQu ...

  5. Mysql 简单问题汇总(持续更新)

    主从架构相关问题 问题现象:从机连接主机时报错 [ERROR] Slave I/O: error connecting to master 'repl@192.168.0.50:3306' - ret ...

  6. Collection中的排序

    我们来了解一下Collection的框架与接口: Set接口下面已经有SortedSet接口,其中提供了很多自带排序的实现类,例如ThreeSet,用户还能够自定义比较器来规定自己的排序规则. 本篇着 ...

  7. Oracle出现字符集问题处理方法

    1.  Cmd进去DOS 2.  再输入dbca(database  create) 3.  弹出的界面,直接下一步,选择删除数据库 4.  成功删除后,回到一第一界面,选择创建数据库,下一步. 5. ...

  8. hdu 4417 Super Mario/树套树

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意很简单,给定一个序列求一个区间 [L, R,]中小于等于H的元素的个数. 好像函数式线段树可 ...

  9. javascript面向对象和原型

    /* //工厂模式 function createObject(name,age){ var obj = new Object();//新建一个对象 obj.name=name;//新建对象的属性 o ...

  10. Android 创建单例模式的几种方法

    java模式之单例模式:单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例.特点:1,一个类只能有一个实例2,自己创建这个实例3,整个系统都要使用这个实例 Singleton模式 ...