Description

给定一个长为\(n(n<=10^5)\)的数组

数组里的数不超过\(10^6\)

有两种操作:

1:求\(sum[l,r]\);

2:对\([l,r]\)中的所有数和\(x\)异或

Input

第一行一个整数\(n\),代表有一个长度为\(n\)的数组。

第二行\(n\)个整数,代表\(a_i\)

第三行为一个整数\(m\),代表有\(m\)次操作。

接下来\(m\)行每行描述一个操作。

Output

对于每一个操作\(1\),输出一行代表\(sum[l,r]\).

这题不错,线段树+二进制拆位

由于异或不具有叠加性,所以不能用\(lazy\)标记直接异或。

我们记录\(tr[o][i]\)代表当前节点\(o\),二进制位\(i\)上是\(1\)的数有多少个。

由于,如果某一二进制位上原来为\(1\),且当前异或的数\(x\),当前二进制位上也有\(1\),那么我们的当前\(tr[o][i]=r-l+1-tr[o][i]\)。

可以理解为\(01\)交换。

然后由于\(2^{20}\)比\(10^6\)要大。

所以只需要拆到\(20\)即可。

然后直接计算即可。

PS:记得开\(long \ long\)!

代码

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<iostream>
  4. #define int long long
  5. #define R register
  6. using namespace std;
  7. const int gz=1e5+8;
  8. inline void in(R int &x)
  9. {
  10. R int f=1;x=0;char s=getchar();
  11. while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
  12. while(isdigit(s)){x=x*10+s-'0';s=getchar();}
  13. x*=f;
  14. }
  15. int n,tr[gz<<2][21],tg[gz<<2],m;
  16. #define ls o<<1
  17. #define rs o<<1|1
  18. inline void up(R int o)
  19. {
  20. for(R int i=20;~i;i--)
  21. tr[o][i]=tr[ls][i]+tr[rs][i];
  22. }
  23. void build(R int o,R int l,R int r)
  24. {
  25. if(l==r)
  26. {
  27. R int x;in(x);
  28. for(R int i=20;~i;i--)
  29. if((x>>i)&1)tr[o][i]++;
  30. return;
  31. }
  32. R int mid=(l+r)>>1;
  33. build(ls,l,mid);
  34. build(rs,mid+1,r);
  35. up(o);
  36. }
  37. inline void down(R int o,R int l,R int r)
  38. {
  39. if(tg[o]==0)return;
  40. tg[ls]^=tg[o];tg[rs]^=tg[o];
  41. R int mid=(l+r)>>1;
  42. for(R int i=20;~i;i--)
  43. {
  44. if((tg[o]>>i)&1)
  45. tr[ls][i]=mid-l+1-tr[ls][i],
  46. tr[rs][i]=r-mid-tr[rs][i];
  47. }
  48. tg[o]=0;
  49. return;
  50. }
  51. void change(R int o,R int l,R int r,R int x,R int y,R int k)
  52. {
  53. if(x<=l and y>=r)
  54. {
  55. tg[o]^=k;
  56. for(R int i=20;~i;i--)
  57. if((k>>i)&1)
  58. tr[o][i]=r-l+1-tr[o][i];
  59. return;
  60. }
  61. down(o,l,r);
  62. int mid=(l+r)>>1;
  63. if(x<=mid)change(ls,l,mid,x,y,k);
  64. if(y>mid) change(rs,mid+1,r,x,y,k);
  65. up(o);
  66. }
  67. int query(R int o,R int l,R int r,R int x,R int y)
  68. {
  69. if(x<=l and y>=r)
  70. {
  71. R int res=0;
  72. for(R int i=20;~i;i--)
  73. res+=(1<<i)*tr[o][i];
  74. return res;
  75. }
  76. down(o,l,r);
  77. R int mid=(l+r)>>1,as=0;
  78. if(x<=mid)as+=query(ls,l,mid,x,y);
  79. if(y>mid)as+=query(rs,mid+1,r,x,y);
  80. return as;
  81. }
  82. signed main()
  83. {
  84. in(n);build(1,1,n);in(m);
  85. for(R int opt,l,r,x;m;m--)
  86. {
  87. in(opt);
  88. if(opt==1)
  89. {
  90. in(l),in(r);
  91. printf("%lld\n",query(1,1,n,l,r));
  92. }
  93. else
  94. {
  95. in(l),in(r),in(x);
  96. change(1,1,n,l,r,x);
  97. }
  98. }
  99. }

线段树+二进制位拆分【CF242E】XOR on Segment的更多相关文章

  1. CF242E XOR on Segment

    CF242E XOR on Segment codeforces 洛谷 关于异或,无法运用懒标记实现区间异或: 可以像trie树一样拆位,将每个值拆成二进制数,对此建相应个数的线段树. 0 1与 0异 ...

  2. 线段树+离散化 IP地址段检查 SEGMENT TREE

    Problem: Give a series of IP segments, for example, [0.0.0.1-0.0.0.3], [123.234.232.21-123.245.21.1] ...

  3. CodeForces 242E "XOR on Segment"(线段树)

    传送门 •题意 给你一个包含 n 个数的序列 a,定义序列上的两个操作: (1)$1,l,r\ :\ ans=\sum_{i=l}^{r}a_i$; (2)$2,l,r,x\ :\ \forall\ ...

  4. codeforces 22E XOR on Segment 线段树

    题目链接: http://codeforces.com/problemset/problem/242/E E. XOR on Segment time limit per test 4 seconds ...

  5. Codeforces 242E:XOR on Segment(位上的线段树)

    http://codeforces.com/problemset/problem/242/E 题意:给出初始n个数,还有m个操作,操作一种是区间求和,一种是区间xor x. 思路:昨天比赛出的一道类似 ...

  6. codeforces 242E - XOR on Segment (线段树 按位数建树)

    E. XOR on Segment time limit per test 4 seconds memory limit per test 256 megabytes input standard i ...

  7. 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. 这题 ...

  8. CodeForces 242E - XOR on Segment 二维线段树?

    今天练习赛的题....又是线段树的变换..拿到题我就敲了个点更新区间查询的..果断超时...然后想到了可以将每个数与合表示成不进位的二进制数..这样就可以区间进行更新了..比赛的时候写搓了..刚重写了 ...

  9. codeforces 242E. XOR on Segment 线段树

    题目链接 给n个数, 两种操作, 一种是求区间内的数的和, 一种是将区间内的数异或x. 异或x没有什么思路, 单个异或肯定超时, 区间异或也没有办法做....后来才知道可以按位建线段树, 这样建20棵 ...

随机推荐

  1. 2017 济南综合班 Day 6

    循环移动 (cyclic.cpp/c/pas) (1s/256M) 问题描述 给出一个字符串S与N个操作.每个操作用三元组(L, R, K)进行描述:操作将字符串第L个到第R个位置构成的子串循环移动K ...

  2. [SCOI2009]生日礼物

    https://www.luogu.org/problem/show?pid=2564 题目描述 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x ...

  3. Jenkenis报错:该jenkins实例似乎已离线[转]

    解决方法: 安装插件那个页面,就是提示你offline的那个页面,不要动.然后打开一个新的tab,输入网址http://localhost:8080/pluginManager/advanced. 这 ...

  4. 【BZOJ】4530: [Bjoi2014]大融合

    [题意]给定n个点的树,从无到有加边,过程中动态询问当前图某条边两端连通点数的乘积,n<=10^5. [算法]线段树合并+并查集 (||LCT(LCT维护子树信息 LCT维护子树信息(+启发式合 ...

  5. 透彻理解Spring事务设计思想之手写实现(山东数漫江湖)

    前言 事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败.事务具有4个特性:Atomicity(原子性),Consistency(一致性),Isolation(隔离性),D ...

  6. DotNETCore 学习笔记 MVC视图

    Razor Syntax Reference Implicit Razor expressions <p>@DateTime.Now</p> <p>@DateTim ...

  7. js_页面关闭beforeunload事件

    做圆桌爆文公众号的时候,需要对阅读的文章进行时间统计.是这个公众号的核心功能,客户把文章转发到朋友圈或者转给朋友,记录谁阅读此文章和阅读时长进行记录,从而展示给客户. 功能点是,关闭页面时触发事件,请 ...

  8. 我的spring boot,杨帆、起航!

    快速新建一个spring boot工程可以去http://start.spring.io/这个网址,配置完后会自动下载一个工程的压缩包,解压后导入相关ide工具即可使用. 工程中会自带一个class启 ...

  9. 修改ES使用root用户运行

    默认ES不允许使用root用户运行,如果使用root会报如下图的错误: ,通常建议创建elsearch用户并使用该用户运行ES.但如果必须使用root用户时,按如下设置即可: 1.启动是使用如下命令 ...

  10. 细数雷军系成员,27家公司3家IPO

    自 2004 年至今,作为天使投资人和顺为基金创始合伙人,雷军共投了移动互联网.电子商务.互联网社区等领域内的 27 家创业公司,其中欢聚时代.猎豹移动.迅雷三家公司成功上市.小米科技虽然还未 IPO ...