codeforces 242E - XOR on Segment (线段树 按位数建树)
4 seconds
256 megabytes
standard input
standard output
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 %I64dspecifier.
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
26
22
0
34
11
6
4 7 4 0 7 3
5
2 2 3 8
1 1 5
2 3 5 1
2 4 5 6
1 2 3
38
28
题意;
两个操作:
1.输出区间l,r的和
2.让区间l,r每个数异或x
思路:
把数拆成二进制,对每一位建一棵线段树,记录每个数这一位是否为1,然后求一段区间的和就是这些线段树上这一段区间1的个数乘上2的位数-1次方,异或一个数x的话,我们将x拆成二进制,如果x的某一位为1的话那么就是对这段区间所有数的这一位都要变化,这一位线段树上直接区间异或标记就好了。
实现代码:
#include<bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid int m = (l + r) >> 1
#define ll long long
const int M = 1e5 + ; int sum[M<<][],lazy[M<<][],a[M],bit[]; void pushup(int rt){
for(int i = ;i <= ;i ++)
sum[rt][i] = sum[rt<<][i] + sum[rt<<|][i];
} void pushdown(int l,int r,int rt){
for(int i = ;i <= ;i ++)
if(lazy[rt][i]){
mid;
sum[rt<<][i] = m-l+-sum[rt<<][i];
sum[rt<<|][i] = r-m-sum[rt<<|][i];
lazy[rt<<][i] ^= lazy[rt][i];
lazy[rt<<|][i] ^= lazy[rt][i];
lazy[rt][i] = ;
}
} void build(int l,int r,int rt){
if(l == r){
int x = a[l],cnt = ;
while(x){
sum[rt][cnt++] = x%;
x = x/;
}
return;
}
mid;
build(lson); build(rson);
pushup(rt);
} void update(int L,int R,int x,int l,int r,int rt){
if(L <= l&&R >= r){
for(int i = ;i <= ;i ++){
if(x&(<<(i-))){
sum[rt][i] = r-l+-sum[rt][i];
lazy[rt][i] ^= ;
}
}
return ;
}
pushdown(l,r,rt);
mid;
if(L <= m) update(L,R,x,lson);
if(R > m) update(L,R,x,rson);
pushup(rt);
} ll query(int L,int R,int l,int r,int rt){
if(L <= l&&R >= r){
ll cnt = ;
for(int i = ;i <= ;i ++){
cnt += 1LL*sum[rt][i]*bit[i];
}
return cnt;
}
pushdown(l,r,rt);
mid; ll ret = ;
if(L <= m) ret += query(L,R,lson);
if(R > m) ret += query(L,R,rson);
return ret;
} int main(){
int n,q,l,r,x,op;
bit[] = ;
for(int i = ;i <= ;i ++)
bit[i] = bit[i-]*;
while(scanf("%d",&n)!=EOF){
for(int i = ;i <= n;i ++)
scanf("%d",&a[i]);
build(,n,);
scanf("%d",&q);
while(q--){
scanf("%d",&op);
if(op == ){
scanf("%d%d",&l,&r);
printf("%lld\n",query(l,r,,n,));
}
else{
scanf("%d%d%d",&l,&r,&x);
update(l,r,x,,n,);
}
}
}
return ;
}
codeforces 242E - XOR on Segment (线段树 按位数建树)的更多相关文章
- codeforces 242E. XOR on Segment 线段树
题目链接 给n个数, 两种操作, 一种是求区间内的数的和, 一种是将区间内的数异或x. 异或x没有什么思路, 单个异或肯定超时, 区间异或也没有办法做....后来才知道可以按位建线段树, 这样建20棵 ...
- codeforces 22E XOR on Segment 线段树
题目链接: http://codeforces.com/problemset/problem/242/E E. XOR on Segment time limit per test 4 seconds ...
- 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 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 516C Drazil and Park 线段树
原文链接http://www.cnblogs.com/zhouzhendong/p/8990745.html 题目传送门 - CodeForces 516C 题意 在一个环上,有$n$棵树. 给出每一 ...
随机推荐
- Python全栈开发之路 【第六篇】:Python基础之常用模块
本节内容 模块分类: 好处: 标准库: help("modules") 查看所有python自带模块列表 第三方开源模块: 自定义模块: 模块调用: import module f ...
- 基于 Token 的身份验证:JSON Web Token(附:Node.js 项目)
最近了解下基于 Token 的身份验证,跟大伙分享下.很多大型网站也都在用,比如 Facebook,Twitter,Google+,Github 等等,比起传统的身份验证方法,Token 扩展性更强, ...
- 【fetch跨域请求】cors
当使用fetch 发起跨域请求时,CORS(跨域资源共享Cross-origin resource sharing) 请求fetch const body = {name:"Good boy ...
- Python入门-用户登录程序
_flag = Falsecount = 0users = [['ziv', '123'], ['alex', '12345']]while count < 3: username = inpu ...
- Tomcat搭建Web 应用服务器
和安卓联合开发,测试手机设配效果,被安卓开发大神同事一顿鄙视之后,愤然而起自己搭建了一个本地服务器(愤怒 玻璃心使我成长~哈哈) java+tomcat安装 java安装 注册oracle账号: 手机 ...
- Linux Centos 迁移Mysql 数据位置
Linux Centos 迁移Mysql 数据位置 由于业务量增加导致安装在系统盘(20G)磁盘空间被占满了, 现在进行数据库的迁移. Mysql 是通过 yum 安装的. Centos6.5Mysq ...
- [转帖]CentOS 6 服务器安全配置指南(通用)
CentOS 6 服务器安全配置指南(通用) http://seanlook.com/2014/09/07/linux-security-general-settings/ 发表于 2014-09- ...
- cmd远程连接oracle数据库
- 搭建ELK日志分析系统
看了辣么多博客,就数这个最详细最容易理解了:https://blog.csdn.net/qq_22211217/article/details/80764568 >>>>> ...
- js中的call、apply、bind
在js中每个函数都包含两个非继承而来的方法:call()和apply() call和apply的作用都是在特定的作用域中将函数绑定到另外一个对象上去运行,即可以用来重新定义函数的执行环境,两者仅在定义 ...