Codeforces242E XOR on Segment(线段树)
2016-07-29 19:43
204 查看
Codeforces242E XOR on Segment
题意:
有一个长度为n的数列,给出两种操作:
1.对区间(l,r)求和并输出。
2.对区间(l,r)内的所有数都修改为原来的数异或x后得到的值。
分析:
线段树,延迟标记,区间求和,但维护不能直接维护求和的值,因为有异或操作,所以将数拆成二进制,记录每一位出现的次数,每异或一次,就相当于将区间和各二进制位0变1、1变0,求和计算一下即可。
题意:
有一个长度为n的数列,给出两种操作:
1.对区间(l,r)求和并输出。
2.对区间(l,r)内的所有数都修改为原来的数异或x后得到的值。
分析:
线段树,延迟标记,区间求和,但维护不能直接维护求和的值,因为有异或操作,所以将数拆成二进制,记录每一位出现的次数,每异或一次,就相当于将区间和各二进制位0变1、1变0,求和计算一下即可。
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <queue> using namespace std; typedef long long LL; typedef double DB; #define INF 2147483647 #define mms(_x, _y) memset(_x, _y, sizeof(_x)); #define rep(_x, _y, _z) for(int _x = _y; _x <= _z; _x++) #define per(_x, _y, _z) for(int _x = _y; _x >= _z; _x--) const int MOD=1e6+3; const double pi = acos(-1.0); const double E = exp(1.0); const int M = 1e5+9; struct node{ int xo[25]; LL su[25]; }tn[M*4]; int n,m,nu[M],change[25],cl,cr,cx,type,cd; LL Quick_pow(LL qx, LL qa){ LL qans = 1; while(qa){ if(qa&1)qans*=qx; qx*=qx; qa>>=1; } return qans; } void Inittree(int rt,int l,int r){ mms(tn[rt].xo,0); mms(tn[rt].su,0); if(l==r){ int d=0; while(nu[l]){ tn[rt].su[d]=nu[l]&1; nu[l]>>=1; d++; } return; } int mid=l+r>>1; Inittree(rt*2+1,l,mid); Inittree(rt*2+2,mid+1,r); rep(i,0,21)tn[rt].su[i]=tn[rt*2+1].su[i]+tn[rt*2+2].su[i]; } void update(int rt,int l,int r){ if(cl>r||cr<l)return; if(cl<=l&&cr>=r){ rep(i,0,21)tn[rt].xo[i]+=change[i]; rep(i,0,21)if(change[i])tn[rt].su[i]=r-l+1-tn[rt].su[i]; return; } int mid=l+r>>1; rep(i,0,21){ if(tn[rt].xo[i]%2){ tn[rt*2+1].xo[i]+=1; tn[rt*2+2].xo[i]+=1; tn[rt*2+1].su[i]=mid-l+1-tn[rt*2+1].su[i]; tn[rt*2+2].su[i]=r-mid-tn[rt*2+2].su[i]; tn[rt].xo[i]=0; } } update(rt*2+1,l,mid); update(rt*2+2,mid+1,r); rep(i,0,21)tn[rt].su[i]=tn[rt*2+1].su[i]+tn[rt*2+2].su[i]; } LL find(int rt,int l,int r){ LL ans=0; if(cl>r||cr<l)return 0; if(cl<=l&&cr>=r){ rep(i,0,21)ans+=tn[rt].su[i]*Quick_pow(2,i); } e 4000 lse{ int mid=l+r>>1; rep(i,0,21){ if(tn[rt].xo[i]%2){ tn[rt*2+1].xo[i]+=1; tn[rt*2+2].xo[i]+=1; tn[rt*2+1].su[i]=mid-l+1-tn[rt*2+1].su[i]; tn[rt*2+2].su[i]=r-mid-tn[rt*2+2].su[i]; tn[rt].xo[i]=0; } } ans=find(rt*2+1,l,mid)+find(rt*2+2,mid+1,r); } return ans; } void Init(){ scanf("%d",&n); rep(i,1,n)scanf("%d",&nu[i]); Inittree(0,1,n); scanf("%d",&m); } void Solve(){ while(m--){ scanf("%d%d%d",&type,&cl,&cr); if(type==1)printf("%I64d\n",find(0,1,n)); else{ scanf("%d",&cx); mms(change,0); cd=0; while(cx){ change[cd]=cx&1; cx>>=1; cd++; } update(0,1,n); } } } int main(){ int _T = 1; //scanf("%d",&_T); while(_T--){ Init(); Solve(); } return 0; }
相关文章推荐
- HDU1166 (线段树/修改点,询问区间)
- hdu 1698 Just a Hook 线段树区间更新
- C语言线段树
- 经典算法题每日演练——第十二题 线段树
- hdu 1394 Minimum Inversion Number 【线段树查找】
- fzu_noip 1039(盖楼-线段树)
- 线段树(带删除节点)
- HDU 3265 Posters(线段树)
- 【CQBZOJ 2856】[线段树]原子核研究
- POJ - 3667 线段树区间合并
- POJ 2104/HDU 2665 区间k大值 函数式线段树
- hdu2665 可持续化线段树
- hdoj 4509 湫湫系列故事——减肥记II 【线段树】
- qscoj:喵哈哈村的冒菜店(线段树区间合并)
- HDU 1698 Just a Hook(线段树区间更新+区间求和+染色问题)
- tyvj1038--忠诚(线段树)
- 【BZOJ】【P1858】【Scoi2010】【序列操作】【题解】【线段树】
- poj 2528 Mayor's posters(线段树+离散化)
- Codeforces Round #406 (Div. 2) D. Legacy 线段树建模+最短路
- CodeChef:Chef and Subarray Queries(线段树)