题意:

给出区间与、或、异或\(x\)操作,还有询问区间和。

思路:

因为数比较小,我们给每一位建线段树,这样每次只要更新对应位的答案。

与\(0\)和或\(1\)相当于重置区间,异或\(1\)相当于翻转区间,那么设出两个\(lazy\)搞一下。注意父区间\(pushdown\)重置标记时,子区间的翻转标记要清空。

代码:

  1. #include <map>
  2. #include <set>
  3. #include <queue>
  4. #include <cmath>
  5. #include <stack>
  6. #include <ctime>
  7. #include <vector>
  8. #include <cstdio>
  9. #include <string>
  10. #include <cstring>
  11. #include <sstream>
  12. #include <iostream>
  13. #include <algorithm>
  14. typedef long long ll;
  15. typedef unsigned long long ull;
  16. using namespace std;
  17. const int maxn = 1e6 + 5;
  18. const int MAXM = 3e6;
  19. const ll MOD = 1e9 + 7;
  20. const ull seed = 131;
  21. const int INF = 0x3f3f3f3f;
  22. #define lson (rt << 1)
  23. #define rson (rt << 1 | 1)
  24. int sum[5][maxn << 2];
  25. int lazy[5][maxn << 2], rev[5][maxn << 2];
  26. int a[maxn];
  27. void pushup(int rt, int bit){
  28. sum[bit][rt] = sum[bit][lson] + sum[bit][rson];
  29. }
  30. void pushdown(int rt, int bit, int l, int r){
  31. int m = (l + r) >> 1;
  32. if(lazy[bit][rt] != -1){
  33. sum[bit][lson] = lazy[bit][rt] * (m - l + 1);
  34. sum[bit][rson] = lazy[bit][rt] * (r - m);
  35. lazy[bit][lson] = lazy[bit][rson] = lazy[bit][rt];
  36. rev[bit][lson] = rev[bit][rson] = 0; //!!!!!
  37. lazy[bit][rt] = -1;
  38. }
  39. if(rev[bit][rt]){
  40. sum[bit][lson] = m - l + 1 - sum[bit][lson];
  41. sum[bit][rson] = r - m - sum[bit][rson];
  42. rev[bit][lson] ^= 1;
  43. rev[bit][rson] ^= 1;
  44. rev[bit][rt] = 0;
  45. }
  46. }
  47. void build(int l, int r, int bit, int rt){
  48. lazy[bit][rt] = -1;
  49. rev[bit][rt] = 0;
  50. if(l == r){
  51. sum[bit][rt] = (a[l] >> bit) & 1;
  52. return;
  53. }
  54. int m = (l + r) >> 1;
  55. build(l, m, bit, lson);
  56. build(m + 1, r, bit, rson);
  57. pushup(rt, bit);
  58. }
  59. void update(int L, int R, int l, int r, int op, int bit, int rt){
  60. if(L <= l && R >= r){
  61. if(op == 1){ //&0
  62. lazy[bit][rt] = 0;
  63. rev[bit][rt] = 0;
  64. sum[bit][rt] = 0;
  65. }
  66. else if(op == 2){ //|1
  67. lazy[bit][rt] = 1;
  68. rev[bit][rt] = 0;
  69. sum[bit][rt] = r - l + 1;
  70. }
  71. else{ //^1
  72. rev[bit][rt] ^= 1;
  73. sum[bit][rt] = r - l + 1 - sum[bit][rt];
  74. }
  75. return;
  76. }
  77. pushdown(rt, bit, l, r);
  78. int m = (l + r) >> 1;
  79. if(L <= m)
  80. update(L, R, l, m, op, bit, lson);
  81. if(R > m)
  82. update(L, R, m + 1, r, op, bit, rson);
  83. pushup(rt, bit);
  84. }
  85. int query(int L, int R, int l, int r, int bit, int rt){
  86. if(L <= l && R >= r){
  87. return sum[bit][rt];
  88. }
  89. pushdown(rt, bit, l, r);
  90. int m = (l + r) >> 1, ret = 0;
  91. if(L <= m)
  92. ret += query(L, R, l, m, bit, lson);
  93. if(R > m)
  94. ret += query(L, R, m + 1, r, bit, rson);
  95. return ret;
  96. }
  97. int main(){
  98. int n, m, T;
  99. scanf("%d", &T);
  100. while(T--){
  101. scanf("%d%d", &n, &m);
  102. for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
  103. for(int i = 0; i < 5; i++) build(1, n, i, 1);
  104. while(m--){
  105. int op, l, r, x;
  106. char ope[10];
  107. scanf("%s", &ope);
  108. if(ope[0] == 'A') op = 1;
  109. else if(ope[0] == 'O') op = 2;
  110. else if(ope[0] == 'X') op = 3;
  111. else op = 4;
  112. if(op == 4){
  113. scanf("%d%d", &l, &r);
  114. l++, r++;
  115. ll ans = 0;
  116. for(int i = 0; i < 5; i++){
  117. x = query(l, r, 1, n, i, 1);
  118. ans += 1LL * (1LL << i) * x;
  119. }
  120. printf("%lld\n", ans);
  121. }
  122. else{
  123. scanf("%d%d%d", &x, &l, &r);
  124. l++, r++;
  125. if(op == 2 || op == 3){
  126. for(int i = 0; i < 5; i++){
  127. if((x >> i) & 1)
  128. update(l, r, 1, n, op, i, 1);
  129. }
  130. }
  131. else{
  132. for(int i = 0; i < 5; i++){
  133. if(!((x >> i) & 1))
  134. update(l, r, 1, n, op, i, 1);
  135. }
  136. }
  137. }
  138. }
  139. }
  140. return 0;
  141. }

FZU2105 Digits Count(按位建线段树)题解的更多相关文章

  1. FZU-2105 Digits Count (两种标记成段更新)

    题目大意:给n个0~15之间的数,有3种更新操作,1种询问操作.3种更新操作是:1.让某个闭区间的所有数字与一个0~15之间的数字进行逻辑与运算:2.让某个闭区间的所有数字与一个0~15之间的数字进行 ...

  2. bzoj 4311 向量 时间线建线段树+凸包+三分

    题目大意 你要维护一个向量集合,支持以下操作: 1.插入一个向量(x,y) 2.删除插入的第i个向量 3.查询当前集合与(x,y)点积的最大值是多少.如果当前是空集输出0 分析 按时间线建线段树 大致 ...

  3. FZU 2105 Digits Count(按位维护线段树)

    [题目链接] http://acm.fzu.edu.cn/problem.php?pid=2105 [题目大意] 给出一个序列,数字均小于16,为正数,每次区间操作可以使得 1. [l,r]区间and ...

  4. Count the Colors(线段树染色)

    Count the Colors Time Limit:2000MS    Memory Limit:65536KB    64bit IO Format:%lld & %llu Submit ...

  5. HDU 6155 Subsequence Count(矩阵乘法+线段树+基础DP)

    题意 给定一个长度为 \(n\) 的 \(01\) 串,完成 \(m\) 种操作--操作分两种翻转 \([l,r]\) 区间中的元素.求区间 \([l,r]\) 有多少个不同的子序列. \(1 \le ...

  6. 【GDKOI2016Day1T1-魔卡少女】【拆位】线段树维护区间内所有连续子区间的异或和

    题意:给出N个数,M个操作.操作有修改和询问两种,每次修改将一个数改成另一个数,每次询问一个区间的所有连续子区间的异或和.n,m<=100000,ai<=1000 题解: 当年(其实也就是 ...

  7. ZOJ 1610——Count the Colors——————【线段树区间替换、求不同颜色区间段数】

    Count the Colors Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Subm ...

  8. bzoj 4184 shallot 时间线建线段树+vector+线性基

    题目大意 n个时间点 每个时间点可以插入一个权值或删除一个权值 求每个时间点结束后异或最大值 分析 异或最大值用线性基 但是线性基并不支持删除操作 我们可以对时间线建一棵线段树 离线搞出每个权值出现的 ...

  9. ZOJ - 1610 Count the Colors(线段树区间更新,单点查询)

    1.给了每条线段的颜色,存在颜色覆盖,求表面上能够看到的颜色种类以及每种颜色的段数. 2.线段树区间更新,单点查询. 但是有点细节,比如: 输入: 2 0 1 1 2 3 1 输出: 1 2 这种情况 ...

随机推荐

  1. MySQL 5.6.35 索引优化导致的死锁案例解析

    一.背景 随着公司业务的发展,商品库存从商品中心独立出来成为一个独立的系统,承接主站商品库存校验.订单库存扣减.售后库存释放等业务.在上线之前我们对于核心接口进行了压测,压测过程中出现了 MySQL ...

  2. django 中连接mysql数据库的操作步骤

    django中连接mysql数据库的操作步骤: 1 settings配置文件中 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mys ...

  3. Py-面向对象,组合,继承

    面向对象 只有特定对象能使用特定的几个方法对象=特征+动作 def dog(name,gender,type): #狗的动作 def jiao(dog): print('一条狗%s,汪汪汪' %dog ...

  4. k8s之PV、PVC、StorageClass详解

    导读 上一篇写了共享存储的概述以及一个简单的案例演示.这一篇就写一下PV和PVC. PV是对底层网络共享存储的抽象,将共享存储定义为一种"资源",比如Node也是容器应用可以消费的 ...

  5. 阿里云 CentOS7中搭建FTP服务器

    1配置 vsftpd-3.0.2-27.el7.x86_64 阿里云 centos 7.0 2 ftp工作模式 2.1 ftp通道 ftp工作会启动两个通道: 控制通道,数据通道 在ftp协议中,控制 ...

  6. (16)-Python3之--自定义logging日志模块

    1.自定义的日志模块如下: import logging from logging.handlers import TimedRotatingFileHandler import datetime f ...

  7. 通俗易懂的解释:什么是API

    API 全称 Application Programming Interface,即应用程序编程接口. 看到这里,急性子的小白同学马上就憋不住了:这不管是英文还是中文我每个字都懂啊,只是凑一块就不知道 ...

  8. AES 密钥与 RSA 密钥的关系

    AES 加密说明 - 支付宝开放平台 https://opendocs.alipay.com/open/common/104567 AES 密钥是对接口请求和响应内容进行加密,密文无法被第三方识别,从 ...

  9. SpringMVC听课笔记(五:处理模型数据)

    1. Spring MVC 提供了以下几种途径输出数据模型 -- ModelAndView: 处理方法返回值类型为ModelAndView 时,方法体即可通过该对象添加模型数据 -- Map及Mode ...

  10. 三:SpringBoot-配置系统全局异常映射处理

    三:SpringBoot-配置系统全局异常映射处理 1.异常分类 1.1 业务异常 1.2 系统异常 2.自定义异常处理 2.1 自定义业务异常类 2.2 自定义异常描述对象 2.3 统一异常处理格式 ...