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-正则表达式总结版
前言: 总是写不好正则表达式,时间长不用就有些忘记了,故此在总结一篇文章以便日后查阅. 一.常用的匹配规则总结表 模式 描述 \w 匹配字母数字及下划线 \W 匹配非字母数字及下划线 \s 匹配任意空 ...
- 【fetch跨域请求】cors
当使用fetch 发起跨域请求时,CORS(跨域资源共享Cross-origin resource sharing) 请求fetch const body = {name:"Good boy ...
- HDU - 1698 线段树区间修改,区间查询
这就是很简单的基本的线段树的基本操作,区间修改,区间查询,对区间内部信息打上laze标记,然后维护即可. 我自己做的时候太傻逼了...把区间修改写错了,对给定区间进行修改的时候,mid取的是节点的左右 ...
- iOS- 利用AFNetworking(AFN) - 实现文件断点下载
https://www.cnblogs.com/qingche/p/3500746.html 1. 定义一个全局的AFHttpClient:包含有 1> baseURL 2> 请求 3&g ...
- SpringMVC controller 时间 T
Spring MVC 之 处理Date类型 - carl.zhao的专栏 - CSDN博客https://blog.csdn.net/u012410733/article/details/727730 ...
- [转帖]浅谈程序中的text段、data段和bss段
作者:百问科技链接:https://zhuanlan.zhihu.com/p/28659560来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 一般情况,一个程序本质上都 ...
- pojo类自动生成序列化ID
自动生成序列化ID
- Spring boot 将配置文件属性注入到一个bean中
现在要做的就是将如下配置文件中的内容注入到一个bean 名为Properties中. Redis.properties配置文件中的内容如下: Properties java bean中代码如下,注意注 ...
- 剑指offer(12)
来两道关于链表链接的题目: 题目一: 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 本题要考虑到其中一条链表是空或者两个都是空的情况. 在每个链表安上一 ...
- Python:matplotlib绘制散点图
与线型图类似的是,散点图也是一个个点集构成的.但不同之处在于,散点图的各点之间不会按照前后关系以线条连接起来. 用plt.plot画散点图 奇怪,代码和前面的例子差不多,为什么这里显示的却是散 ...