CF 242E XOR on Segment
来源:互联网 发布:知乎德国白啤酒 编辑:程序博客网 时间:2024/09/21 08:16
题目链接:http://codeforces.com/problemset/problem/242/E
题目大意:
给定一个长为n(n<=10^5)的数组,数组里的数不超过10^6,有两种操作
1:求sum[l,r]; 2:对[l,r]中的所有数和x异或
题目思路:
一看题目,摆明了是成段更新的线段树,但是异或不符合分配律的( (a+b)^x != a^x+b^x ),但是我们知道异或对于一个数上的二进制表达式的所有位是独立的,又知道数组中的数不超过10^6,二进制大概是20位,所以我们线段树就维护该段中所有数的某一位上有几个1和0即可.
代码:
#include <stdlib.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include <math.h>#include <stack>#include <queue>#include <map>#include <set>#include <vector>#include <string>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define ls rt<<1#define rs ls|1#define lson l,mid,ls#define rson mid+1,r,rs#define middle (l+r)>>1#define eps (1e-9)#define type int#define clr_all(x,c) memset(x,c,sizeof(x))#define clr(x,c,n) memset(x,c,sizeof(x[0])*(n+1))#define MOD 1000000007#define inf 0x3f3f3f3f#define pi acos(-1.0)#define _max(x,y) (((x)>(y))? (x):(y))#define _min(x,y) (((x)<(y))? (x):(y))#define _abs(x) ((x)<0? (-(x)):(x))#define getmin(x,y) (x= (x==-1 || (y)<x)? (y):x)#define getmax(x,y) (x= ((y)>x)? (y):x)template <class T> void _swap(T &x,T &y){T t=x;x=y;y=t;}int TS,cas;const int M=100000+5;int n,m;int sum[M<<2][20][2],cov[M<<2],ret[20];void pushUp(int rt){for(int i=0;i<20;i++)for(int j=0;j<2;j++)sum[rt][i][j]=sum[ls][i][j]+sum[rs][i][j];}void build(int l,int r,int rt){if(l==r){int a;scanf("%d",&a);clr_all(sum[rt],0),cov[rt]=0;for(int i=0;i<20;i++,a/=2)sum[rt][i][a&1]++;return;}int mid=middle;build(lson),build(rson);pushUp(rt);}void pushDown(int rt){if(!cov[rt]) return;cov[ls]^=cov[rt],cov[rs]^=cov[rt];for(int i=0;cov[rt];i++,cov[rt]/=2) if(cov[rt]&1){_swap(sum[ls][i][0],sum[ls][i][1]);_swap(sum[rs][i][0],sum[rs][i][1]);}}void update(int l,int r,int rt,int L,int R,int c){if(L<=l && r<=R){cov[rt]^=c;int i;for(i=0;c;i++,c/=2) if(c&1)_swap(sum[rt][i][0],sum[rt][i][1]);return;}pushDown(rt);int mid=middle;if(L<=mid) update(lson,L,R,c);if(mid<R) update(rson,L,R,c);pushUp(rt);}void query(int l,int r,int rt,int L,int R){if(L<=l && r<=R){for(int i=0;i<20;i++)ret[i]+=sum[rt][i][1];return;}pushDown(rt);int mid=middle;if(L<=mid) query(lson,L,R);if(mid<R) query(rson,L,R);}void run(){int i,j;build(1,n,1);scanf("%d",&m);int t,l,r,x;while(m--){scanf("%d%d%d",&t,&l,&r);if(t==1){clr_all(ret,0);query(1,n,1,l,r);ll ans=0,g=0,pw2=1,c;for(i=0;i<20 || g;i++,pw2*=2){c=g+((i<20)? ll(ret[i]):0);ans+=(c%2)*pw2;g=c/2;}printf("%I64d\n",ans);}else{scanf("%d",&x);update(1,n,1,l,r,x);}}}void preSof(){}int main(){//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);preSof();//run();while(~scanf("%d",&n)) run();//for(scanf("%d",&TS),cas=1;cas<=TS;cas++) run();return 0;}
- CF 242E XOR on Segment
- CF 242E XOR on Segment 【线段树】
- CF 242E XOR on Segment(二维线段树)
- codeforces 242E XOR on Segment
- 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(线段树)
- Codeforces 242E- XOR on Segment(线段树)
- Codeforces-242E:XOR on Segment(20个线段树)
- Codeforce-242E-XOR on Segment(线段树区间更新)
- Codeforces Round #149 (Div. 2) E. XOR on Segment
- Codeforces Round #149 (Div. 2) E - XOR on Segment
- CF149 E XOR on Segment(线段树成段更新)
- [CF242E]XOR on Segment
- 迁移学习( Transfer Learning )
- 关于用file初始化NSString
- 缓存小小总结
- lib\kobject.c文件分析
- 分布式计算的定义
- CF 242E XOR on Segment
- PHp学习之路二(数组练习)
- Matlab 图像处理相关函数命令大全
- 面向对象设计模式
- 一个女孩的就业之路(同济大学BBS上两年不沉的帖子)
- 变量调节器的剩下几个功能
- 【实例】赵雅智_购物车(1)查询所有书籍
- DSP2812的软件锁相方法
- grails中blank和nullable的区别