考虑暴力,即需要考虑如何实现$\pm 2^{k}$,相当于要找到之后的第一个0或者之前的第一个1(维护区间是否全0/1即可),然后区间重置,可以用线段树维护,复杂度为$o(900n)$(a的划分和线段树),无法通过
但由于数据范围很大,这样过不了,可以想到压位,每30位二进制压为一个数,那么复杂度降为$o(30n)$(因为a只要划分为最多两个数)且常数变小,可以通过

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 #define N 1000100
  4. 4 #define L (k<<1)
  5. 5 #define R (L+1)
  6. 6 #define mid (l+r>>1)
  7. 7 #define S (1<<30)
  8. 8 int n,p,x,y,f[N],laz[N<<2],pos[N<<2],vis[N<<2][2];
  9. 9 int pd(int k){
  10. 10 if (!k)return 0;
  11. 11 if (k==S-1)return 1;
  12. 12 return -1;
  13. 13 }
  14. 14 void build(int k,int l,int r){
  15. 15 laz[k]=-1;
  16. 16 vis[k][0]=1;
  17. 17 if (l==r){
  18. 18 pos[k]=l;
  19. 19 return;
  20. 20 }
  21. 21 build(L,l,mid);
  22. 22 build(R,mid+1,r);
  23. 23 }
  24. 24 void upd(int k,int x){
  25. 25 laz[k]=x;
  26. 26 if (x<0){
  27. 27 vis[k][0]=vis[k][1]=0;
  28. 28 return;
  29. 29 }
  30. 30 if (pos[k])f[pos[k]]=x*(S-1);
  31. 31 vis[k][x]=1;
  32. 32 vis[k][x^1]=0;
  33. 33 }
  34. 34 void up(int k){
  35. 35 vis[k][0]=(vis[L][0]&vis[R][0]);
  36. 36 vis[k][1]=(vis[L][1]&vis[R][1]);
  37. 37 }
  38. 38 void down(int k){
  39. 39 if (laz[k]<0)return;
  40. 40 upd(L,laz[k]);
  41. 41 upd(R,laz[k]);
  42. 42 laz[k]=-1;
  43. 43 }
  44. 44 void update(int k,int l,int r,int x,int y,int z){
  45. 45 if ((l>y)||(x>r))return;
  46. 46 if ((x<=l)&&(r<=y)){
  47. 47 upd(k,z);
  48. 48 return;
  49. 49 }
  50. 50 down(k);
  51. 51 update(L,l,mid,x,y,z);
  52. 52 update(R,mid+1,r,x,y,z);
  53. 53 up(k);
  54. 54 }
  55. 55 int find(int k,int l,int r,int x,int y){
  56. 56 if ((r<=x)||(vis[k][y]))return 0;
  57. 57 if (l==r)return l;
  58. 58 down(k);
  59. 59 int p=find(L,l,mid,x,y);
  60. 60 if (p)return p;
  61. 61 return find(R,mid+1,r,x,y);
  62. 62 }
  63. 63 int query(int k,int l,int r,int x){
  64. 64 if (l==r)return f[l];
  65. 65 down(k);
  66. 66 if (x<=mid)return query(L,l,mid,x);
  67. 67 return query(R,mid+1,r,x);
  68. 68 }
  69. 69 void add(int x,int y){
  70. 70 if (query(1,1,N,x)+y<S){
  71. 71 update(1,1,N,x,x,pd(f[x]+=y));
  72. 72 return;
  73. 73 }
  74. 74 update(1,1,N,x,x,pd(f[x]+=y-S));
  75. 75 int p=find(1,1,N,x,1);
  76. 76 update(1,1,N,x+1,p-1,0);
  77. 77 query(1,1,N,p);
  78. 78 update(1,1,N,p,p,pd(++f[p]));
  79. 79 }
  80. 80 void del(int x,int y){
  81. 81 if (query(1,1,N,x)>=y){
  82. 82 update(1,1,N,x,x,pd(f[x]-=y));
  83. 83 return;
  84. 84 }
  85. 85 update(1,1,N,x,x,pd(f[x]+=S-y));
  86. 86 int p=find(1,1,N,x,0);
  87. 87 update(1,1,N,x+1,p-1,1);
  88. 88 query(1,1,N,p);
  89. 89 update(1,1,N,p,p,pd(--f[p]));
  90. 90 }
  91. 91 int main(){
  92. 92 scanf("%d%*d%*d%*d",&n);
  93. 93 build(1,1,N);
  94. 94 while (n--){
  95. 95 scanf("%d%d",&p,&x);
  96. 96 if (p==2)printf("%d\n",(query(1,1,N,x/30+1)>>(x%30))&1);
  97. 97 else{
  98. 98 scanf("%d",&y);
  99. 99 if (x>0){
  100. 100 add(y/30+1,(x*(1LL<<(y%30))%S));
  101. 101 add(y/30+2,(x*(1LL<<(y%30))/S));
  102. 102 }
  103. 103 else{
  104. 104 x*=-1;
  105. 105 del(y/30+1,(x*(1LL<<(y%30))%S));
  106. 106 del(y/30+2,(x*(1LL<<(y%30))/S));
  107. 107 }
  108. 108 }
  109. 109 }
  110. 110 }

[bzoj4942]整数的更多相关文章

  1. 【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)

    [BZOJ4942][Noi2017]整数 题目描述去uoj 题解:如果只有加法,那么直接暴力即可...(因为1的数量最多nlogn个) 先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依 ...

  2. 【BZOJ4942】[NOI2017]整数(分块)

    [BZOJ4942][NOI2017]整数(分块) 题面 BZOJ 洛谷 题解 暴力就是真正的暴力,直接手动模拟进位就好了. 此时复杂度是模拟的复杂度加上单次询问的\(O(1)\). 所以我们需要优化 ...

  3. BZOJ4942【noi2017】整数

    题目背景 在人类智慧的山巅,有着一台字长为10485761048576 位(此数字与解题无关)的超级计算机,著名理论计算机科 学家P博士正用它进行各种研究.不幸的是,这天台风切断了电力系统,超级计算机 ...

  4. 【bzoj4942】[Noi2017]整数 压位+线段树

    题目描述 P 博士将他的计算任务抽象为对一个整数的操作. 具体来说,有一个整数 $x$ ,一开始为0. 接下来有 $n$ 个操作,每个操作都是以下两种类型中的一种: 1 a b :将 $x$ 加上整数 ...

  5. [BZOJ4942] [NOI2017]整数

    题目背景 在人类智慧的山巅,有着一台字长为1048576位(此数字与解题无关)的超级计算机,著名理论计算机科 学家P博士正用它进行各种研究.不幸的是,这天台风切断了电力系统,超级计算机 无法工作,而 ...

  6. [Bzoj4942][Noi2017]整数(线段树)

    4942: [Noi2017]整数 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 363  Solved: 237[Submit][Status][D ...

  7. BZOJ4942 NOI2017整数(线段树)

    首先把每32位压成一个unsigned int(当然只要压起来能过就行).如果不考虑进/退位的话,每次只要将加/减上去的数拆成两部分直接单点修改就好了.那么考虑如何维护进/退位.可以发现进位的过程其实 ...

  8. 2018.10.30 bzoj4942: [Noi2017]整数(线段树压位)

    传送门 直接把修改的数拆成logloglog个二进制位一个一个修改是会TLETLETLE的. 因此我们把303030个二进制位压成一位储存在线段树里面. 然后维护区间中最靠左二进制位不为0/1的下标. ...

  9. [Noi2017]整数 BZOJ4942

    分析: 30+暴力应该还是蛮水的,可以随便写写... 60+的就没那么容易了,但是应该挺裸的,往上架一颗线段树,查询连续1或0的长度,或者找到前缀中,第一个1或0,之后区间覆盖,单点查询,开bool, ...

随机推荐

  1. 我在阿里巴巴做 Serverless 云开发平台

    技术的成熟度源自大规模的实践,Java 领域,阿里将自身的实践源源不断的反哺给微服务技术体系:Node.js 领域,阿里正掀起了前所未有的前端革命浪潮,将实践反哺给 Serverless技术体系,并逐 ...

  2. Tracking Analyst Tools(Tracking Analyst 工具)

    Tracking Analyst 工具 # Process: 创建追踪图层 arcpy.MakeTrackingLayer_ta("", 输出图层, "NO_TIME_Z ...

  3. asp.net core使用identity+jwt保护你的webapi(三)——refresh token

    前言 上一篇已经介绍了identity的注册,登录,获取jwt token,本篇来完成refresh token. 开始 开始之前先说明一下为什么需要refresh token. 虽然jwt toke ...

  4. logstash输出到rabbitmq

    场景 将应用日志文件发送到rabbitmq. filebeat 不支持rabbitmq作为输出.因此,需要先将文件由filebeat发送到logstash ,再由logstash 输出到rabbitm ...

  5. CF49E Common ancestor(dp+dp+dp)

    纪念卡常把自己卡死的一次自闭模拟赛 QWQ 一开始看这个题,以为是个图论,仔细一想,貌似可以直接dp啊. 首先,因为规则只有从两个变为1个,貌似可以用类似区间\(dp\)的方式来\(check\)一段 ...

  6. bzoj1858SCOI 序列操作 (线段树)

    题目大意: 给定一个长度为n的01序列为,现在有m种操作 \(0\ a\ b\) 把\([a,b]\)的数全部修改为0 \(1\ a\ b\) 把\([a,b]\)的数全部修改为1 \(2\ a\ b ...

  7. Mybatis 一级缓存 (20)

    Mybatis中的一级缓存和二级缓存(本博文只是针对一级缓存说明) 概述 ORM框架一般都会有缓存机制,做为其中一员的Mybatis也存在缓存.功能是用以提升查询的效率和服务给数据库带来压力.同样的M ...

  8. 2021.6.29考试总结[NOIP模拟10]

    T1 入阵曲 二位前缀和暴力n4可以拿60. 观察到维护前缀和时模k意义下余数一样的前缀和相减后一定被k整除,前缀和维护模数,n2枚举行数,n枚举列, 开一个桶记录模数出现个数,每枚举到该模数就加上它 ...

  9. Harbour.Space Scholarship Contest 2021-2022 (Div. 1 + Div. 2) Editorial题解

    A 略,发现只有当末尾为9时才满足条件.. B 简单模拟,注意数组大小!!! C 简单模拟. D 比较暴力的一个做法就是每次找一个开始匹配的起始点,然后每次不同时向后跳2就行了. 注意这里最后还要判断 ...

  10. js 在浏览器中的event loop事件队列

    目录 前言 认识一个栈两个队列 执行过程 异步任务怎么分配 简单例子 难一点的例子 前言 以下内容是js在浏览器中的事件队列执行,与在nodejs中有所区别,请注意. 都说js是单线程的,不过它本身其 ...