CodeForces 242E XOR on Segment 二维线段树
来源:互联网 发布:cf客户端数据异常36 2 编辑:程序博客网 时间:2024/05/22 03:37
题目链接:http://codeforces.com/problemset/problem/242/E
题意:
给定一个长度为n的数组,然后有两种操作。
1:查询操作,求区间[l,r]的值的和;
2:更新操作,区间[l,r]内的每个值与x异或。
分析:
很显然,要用线段树,可是更新时,怎么维护呢?求和很简单,难就难在更新,因为是异或操作,不同于加减操作,可以直接用一维维护。异或操作,需要转换为二进制来计算,那么就再开一维用来记录每个数的二进制情况,然后更新时,只用看对应于x的二进制位1的位置更新,更新时也只需0变1,1变0。就整段区间而言,进行二进制下不进位加法,可以很清晰的记录该区间内每个位置上有多少1。
源代码:
#include<cstdio>#include<cstring>#include<string>#include<queue>#include<map>#include<cmath>#include<stack>#include<vector>#include<iostream>#include<algorithm>using namespace std;const int N=100005;typedef __int64 LL;const LL MOD=1000000007;int tre[N<<2][22],laz[N<<2][22];void build(int o,int l,int r){ if(l==r) { int x; scanf("%d",&x); for(int i=0; i<20; i++) { if(x&(1<<i)) { tre[o][i]=1; laz[o][i]=0; } } return; } int mid=(l+r)/2; build(o<<1,l,mid); build(o<<1|1,mid+1,r); for(int i=0; i<20; i++) tre[o][i]=tre[o<<1][i]+tre[o<<1|1][i];}struct Node{ int a[22];};void pushdown(int o,int mm){ for(int i=0; i<20; i++) { if(laz[o][i]) { tre[o<<1][i]=(mm-mm/2)-tre[o<<1][i]; tre[o<<1|1][i]=mm/2-tre[o<<1|1][i]; laz[o<<1][i]=1-laz[o<<1][i]; laz[o<<1|1][i]=1-laz[o<<1|1][i]; laz[o][i]=0; } }}void update(int o,int l,int r,int x,int y,int c){ if(x<=l&&y>=r) { for(int i=0; i<20; i++) { if(c&(1<<i)) { tre[o][i]=r-l+1-tre[o][i]; laz[o][i]=1-laz[o][i]; } } return; } pushdown(o,r-l+1); int mid=(l+r)/2; if(x<=mid) update(o<<1,l,mid,x,y,c); if(y>mid) update(o<<1|1,mid+1,r,x,y,c); for(int i=0; i<20; i++) tre[o][i]=tre[o<<1][i]+tre[o<<1|1][i];}Node query(int o,int l,int r,int x,int y){ Node h; memset(h.a,0,sizeof(h.a)); if(x<=l&&y>=r) { for(int i=0; i<20; i++) { h.a[i]=tre[o][i]; } return h; } pushdown(o,r-l+1); int mid=(l+r)/2; if(x<=mid) { Node p=query(o<<1,l,mid,x,y); for(int i=0; i<20; i++) h.a[i]+=p.a[i]; } if(y>mid) { Node p=query(o<<1|1,mid+1,r,x,y); for(int i=0; i<20; i++) h.a[i]+=p.a[i]; } return h;}int main(){ int n; while(scanf("%d",&n)!=EOF) { memset(laz,0,sizeof laz); memset(tre,0,sizeof tre); build(1,1,n); int m; scanf("%d",&m); while(m--) { int op,l,r; scanf("%d%d%d",&op,&l,&r); if(op==1) { Node h=query(1,1,n,l,r); LL ans=0; for(int i=0; i<20; i++) { ans+=(LL)h.a[i]*(1<<i); } printf("%I64d\n",ans); } else if(op==2) { int c; scanf("%d",&c); update(1,1,n,l,r,c); } } } return 0;}
0 0
- CodeForces 242E - XOR on Segment 二维线段树?
- CodeForces 242E XOR on Segment 二维线段树
- CF 242E XOR on Segment(二维线段树)
- Codeforces 242E. XOR on Segment【线段树】
- Codeforces 242E XOR on Segment(线段树)
- Codeforces 242E- XOR on Segment(线段树)
- Codeforces-242E:XOR on Segment(20个线段树)
- codeforces 242E XOR on Segment
- Codeforces 242E(XOR on Segment)
- codeforces 242E - XOR on Segment
- CF 242E XOR on Segment 【线段树】
- Codeforces #159 224 E E. XOR on Segment 二十几颗线段树 成段更新 成段求和
- CF 242E-XOR on Segment(线段树区间处理+二进制)
- Codeforce-242E-XOR on Segment(线段树区间更新)
- Codeforces Round #149 (Div. 2) E. XOR on Segment(21棵线段树处理每一位+区间异或)
- CF 242E XOR on Segment
- Codeforces242E XOR on Segment(线段树)
- [CodeForces242E]XOR on Segment-线段树
- @RequestBody获取Json请求数据
- InputStreamReader引发的一个编码问题
- js生成随机数和把日期格式转换成yyyyMMddHHmmss的方法
- 基于cordova插件的上传下载
- 不要问我这是什么!!!
- CodeForces 242E XOR on Segment 二维线段树
- maven坐标Dependencies和Exclusions详解
- 基于HTML5+WebSocket+JAVA的棋牌游戏开发,从入门到放弃(三)
- 美素数
- 2016 Multi-University Training Contest 2 La Vie en rose
- 归并排序
- jdbc批处理大数据
- Linux兴趣小组暑假留校第二次讲座总结
- 解决关于图片大小不一导致Cell的imageView无法显示为圆形