CF 242E(div 2) n课线段树更新
2012-11-17 21:27
537 查看
这类题之前做过1道,是东北网络赛的A题,内题当时没做出来,听了学长的思路后,场下才AC的。。而这题是我完全独立完成,很有纪念意义的。。。嘿嘿。。
话说此题在CF竟然能暴力过关,真心严重B视。。。。应该把时限设在3S内才行。。。
题目是这样说的,做2种操作,一个是计算区间和,还有一个是区间所有数都异或某一个数。普通的成段更新肯定不行,我想到异或是对位计算,那就把1个数转化为二进制后,分位来处理,由于每一位异或1改变值,异或0不变。所以,对某个区间的某一位数异或0时,不改变区间和,若异或1,则总和=区间长度-区间和。。两次异或1为异或0。。代码搞出,后来WA的不明白,把空间改大点,AC了。。。。不容易呀,附代码:
话说此题在CF竟然能暴力过关,真心严重B视。。。。应该把时限设在3S内才行。。。
题目是这样说的,做2种操作,一个是计算区间和,还有一个是区间所有数都异或某一个数。普通的成段更新肯定不行,我想到异或是对位计算,那就把1个数转化为二进制后,分位来处理,由于每一位异或1改变值,异或0不变。所以,对某个区间的某一位数异或0时,不改变区间和,若异或1,则总和=区间长度-区间和。。两次异或1为异或0。。代码搞出,后来WA的不明白,把空间改大点,AC了。。。。不容易呀,附代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #define lson i,l,m,rt<<1 #define rson i,m+1,r,rt<<1|1 #define N 100005 #define M 22 #define ss(a) scanf("%d",&a) #define LL __int64 int sum[M][N*6],col[M][N*6],a[M] ,n; LL c[M]; using namespace std; void init(int j,int x) { int i=0; while (x>0) { if (x&1) a[i][j]=1; else a[i][j]=0; x>>=1; i++; } } void pushup(int i,int rt) { sum[i][rt]=sum[i][rt<<1]+sum[i][rt<<1|1]; } void pushdown(int i,int l,int r,int rt) { if (col[i][rt]%2!=0) { int m=(l+r)>>1; sum[i][rt<<1]=(m-l+1)-sum[i][rt<<1]; sum[i][rt<<1|1]=(r-m)-sum[i][rt<<1|1]; col[i][rt<<1|1]+=col[i][rt]; col[i][rt<<1]+=col[i][rt]; col[i][rt]=0; } } void build(int i,int l,int r,int rt) { if (l==r) { sum[i][rt]=a[i][l]; col[i][rt]=0; return; } int m=(l+r)>>1; build(lson); build(rson); pushup(i,rt); } void update(int L,int R,int i,int l,int r,int rt) { pushdown(i,l,r,rt); if (L<=l&&r<=R) { sum[i][rt]=(r-l+1)-sum[i][rt]; col[i][rt]++; return; } int m=(l+r)>>1; if (L<=m) update(L,R,lson); if (R>m) update(L,R,rson); pushup(i,rt); } int query(int L,int R,int i,int l,int r,int rt) { pushdown(i,l,r,rt); if (L<=l&&r<=R) { return sum[i][rt]; } int m=(l+r)>>1,res=0; if (L<=m) res+=query(L,R,lson); if (R>m) res+=query(L,R,rson); return res; } void bin(int l,int r,int x) { int i=0; while (x>0) { if (x&1) update(l,r,i,1,n,1); x>>=1; i++; } } LL inquery(int l,int r) { LL t,res=0; int i; for (i=0;i<M;i++) { t=query(l,r,i,1,n,1); res+=t*c[i]; } return res; } int main() { int i,z,x,l,r,m; c[0]=1; for (i=1;i<M;i++) c[i]=c[i-1]*2; ss(n); for (i=1;i<=n;i++) { ss(x); init(i,x); } for (i=0;i<M;i++) build(i,1,n,1); ss(m); for (i=1;i<=m;i++) { ss(z); if (z==1) { ss(l);ss(r); LL res=inquery(l,r); printf("%I64d\n",res); } else { ss(l);ss(r);ss(x); bin(l,r,x); } } return 0; }
相关文章推荐
- CF 242E(zkw线段树-拆位)
- cf/Codeforces Round #373 div1-C/div2-E Sasha and Array 线段树 + 维护矩阵快速幂
- Codeforces Round #343 (Div. 2) B. Far Relative’s Problem (线段树+区间更新+单点查询)
- CF 629D Babaei and Birthday Cake(线段树单点更新)
- Educational Codeforces Round 37 (Rated for Div. 2) F. SUM and REPLACE(线段树,区间更新)
- CF 242E-XOR on Segment(线段树区间处理+二进制)
- Codeforces Round #263 (Div. 2)E(线段树点更新)
- Codeforces Round #442 (Div. 2)-E-Danil and a Part-time Job(DFS序+线段树区间更新)
- CF-Div2-207-C题+线段树
- CodeforcesBeta Round #35 (Div. 2) E. Parade(线段树区间更新)
- 【 题集 】 CF #277.5 (Div. 2) 更新ing...
- CF 275 div2 D. Interesting Array (线段树)
- Codeforces Beta Round #75 (Div. 1 Only) B. Queue 线段树。单点更新
- CF 296 div2 C. Glass Carving (线段树)
- [CF#365 (Div. 2) Mishka and Interesting sum] 线段树离线处理区间不同数
- Codeforce-242E-XOR on Segment(线段树区间更新)
- 【线段树延迟更新】Codeforces Round #104 (Div. 1) E
- Codeforces Round #271 (Div. 2)(dp,线段树good)(很好的一场cf)
- CF 179(div2) C(线段树 || 扫描法 )
- Codeforces Round #169 (Div. 2) C. Little Girl and Maximum Sum(线段树区间更新)