题目:https://loj.ac/problem/2302

压30位,a最多落在两个位置上,拆成两次操作。

该位置加了 a 之后,如果要进位或者借位,查询一下连续一段 0 / 1 ,修改掉,再在含有 1 / 0 的那个位置上 -1 或者 +1 。

注意是在那个位置上 -1 或者 +1 而不是 -lowbit 或者 +lowbit 。

询问都是 <=30n ,所以只维护 30n 的范围即可。注意线段树压 30 位,开 n 个位置恰好是 0*n ~ 29*n,所以开 n+1 个位置。

线段树只需维护自己区间是全 0 / 1 还是都有。找连续一段 0/1 就在线段树上二分即可。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #define ls Ls[cr]
  5. #define rs Rs[cr]
  6. using namespace std;
  7. int rdn()
  8. {
  9. int ret=;bool fx=;char ch=getchar();
  10. while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
  11. while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
  12. return fx?ret:-ret;
  13. }
  14. int Mx(int a,int b){return a>b?a:b;}
  15. int Mn(int a,int b){return a<b?a:b;}
  16. const int N=2e6+,bs=;
  17. int n,nr,tot,Ls[N],Rs[N],lx[N],vl[N],tg[N];
  18. int bin[bs+],U; bool fx;
  19. void build(int l,int r,int cr)
  20. {
  21. tg[cr]=-; lx[cr]=vl[cr]=;
  22. if(l==r)return; int mid=l+r>>;
  23. ls=++tot; build(l,mid,ls);
  24. rs=++tot; build(mid+,r,rs);
  25. }
  26. void pshd(int cr)
  27. {
  28. if(tg[cr]==-)return; int k=tg[cr]; tg[cr]=-;
  29. tg[ls]=tg[rs]=k;
  30. if(k==){ vl[ls]=vl[rs]=U; lx[ls]=lx[rs]=;}
  31. else { vl[ls]=vl[rs]=; lx[ls]=lx[rs]=;}
  32. }
  33. void pshp(int cr)
  34. {
  35. if((!lx[ls])&&(!lx[rs]))lx[cr]=;
  36. else if(lx[ls]==&&lx[rs]==)lx[cr]=; else lx[cr]=;
  37. }
  38. void updt(int cr)
  39. { if(!vl[cr])lx[cr]=; else if(vl[cr]==U)lx[cr]=; else lx[cr]=;}
  40. int fnd(int l,int r,int cr,int L,int R,int k)
  41. {
  42. if(l>=L&&r<=R)
  43. {
  44. if(lx[cr]==(!k))return nr+; if(l==r)return l;
  45. int mid=l+r>>; pshd(cr);
  46. if(lx[ls]!=(!k))return fnd(l,mid,ls,L,R,k);
  47. return fnd(mid+,r,rs,L,R,k);
  48. }
  49. int mid=l+r>>,d=nr+; pshd(cr);
  50. if(L<=mid)d=fnd(l,mid,ls,L,R,k);
  51. if(d==nr+)d=fnd(mid+,r,rs,L,R,k);
  52. return d;
  53. }
  54. void mdfy(int l,int r,int cr,int L,int R,int k)
  55. {
  56. if(l>=L&&r<=R)
  57. {
  58. tg[cr]=k; if(k==){vl[cr]=U;lx[cr]=;}
  59. else {vl[cr]=;lx[cr]=;} return;
  60. }
  61. int mid=l+r>>; pshd(cr);
  62. if(L<=mid)mdfy(l,mid,ls,L,R,k);
  63. if(mid<R)mdfy(mid+,r,rs,L,R,k);
  64. pshp(cr);
  65. }
  66. void mdfy2(int l,int r,int cr,int p,int k)
  67. {
  68. if(l==r)
  69. {
  70. if(k==)vl[cr]++; else vl[cr]--;/////
  71. /*if(k==1){ int tmp=(vl[cr]^U); vl[cr]+=(tmp&(-tmp));}
  72. else vl[cr]-=(vl[cr]&(-vl[cr]));*/
  73. updt(cr); return;
  74. }
  75. int mid=l+r>>; pshd(cr);
  76. if(p<=mid)mdfy2(l,mid,ls,p,k);
  77. else mdfy2(mid+,r,rs,p,k);
  78. pshp(cr);
  79. }
  80. void add(int p)
  81. {
  82. int d=fnd(,nr,,p,nr,);//fnd first 0
  83. if(p<d)mdfy(,nr,,p,d-,);
  84. if(d<=nr)mdfy2(,nr,,d,);//chg 0 to 1
  85. }
  86. void dec(int p)
  87. {
  88. int d=fnd(,nr,,p,nr,);
  89. if(p<d)mdfy(,nr,,p,d-,);
  90. if(d<=nr)mdfy2(,nr,,d,);
  91. }
  92. void solve(int l,int r,int cr,int p,int k)
  93. {
  94. if(l==r)
  95. {
  96. if(!fx)vl[cr]+=k; else vl[cr]-=k;
  97. if(vl[cr]>=bin[bs]){ vl[cr]-=bin[bs];add(l+);}
  98. if(vl[cr]<){ vl[cr]+=bin[bs];dec(l+);}
  99. updt(cr); return;
  100. }
  101. int mid=l+r>>; pshd(cr);
  102. if(p<=mid)solve(l,mid,ls,p,k); else solve(mid+,r,rs,p,k);
  103. pshp(cr);
  104. }
  105. bool qry(int l,int r,int cr,int p,int p2)
  106. {
  107. if(l==r)return vl[cr]&bin[p2];
  108. int mid=l+r>>; pshd(cr);
  109. if(p<=mid)return qry(l,mid,ls,p,p2);
  110. else return qry(mid+,r,rs,p,p2);
  111. }
  112. int main()
  113. {
  114. n=rdn(); nr=n+; int tp=rdn();tp=rdn();tp=rdn();
  115. bin[]=;for(int i=;i<=bs;i++)bin[i]=bin[i-]<<;
  116. U=bin[bs]-; tot=;build(,nr,);
  117. for(int i=,op,a,b,l,r;i<=n;i++)
  118. {
  119. op=rdn();
  120. if(op==)
  121. {
  122. a=rdn();b=rdn(); l=b; r=b+bs-;
  123. l=l/bs+; r=r/bs+;
  124. if(a<)a=-a,fx=; else fx=;
  125. if(l<r)
  126. {
  127. int k=a&(bin[l*bs-b]-);
  128. a>>=(l*bs-b); k<<=(b-(l-)*bs);
  129. solve(,nr,,l,k); solve(,nr,,r,a);
  130. }
  131. else solve(,nr,,l,a);
  132. }
  133. else
  134. {
  135. a=rdn(); l=a/bs+; a-=(l-)*bs;
  136. printf("%d\n",qry(,nr,,l,a));
  137. }
  138. }
  139. return ;
  140. }

LOJ 2302 「NOI2017」整数——压位线段树的更多相关文章

  1. LOJ#2302. 「NOI2017」整数

    $n \leq 1000000$个操作:一,给$x$加上$a*2^b$:二,问$x$的某个二进制位$k$.$b,k \leq 30n$,$|a| \leq 1e9$. 30暴露了一切..可以把30个二 ...

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

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

  3. BZOJ 4942 NOI2017 整数 (压位+线段树)

    题目大意:让你维护一个数x(x位数<=3*1e7),要支持加/减a*2^b,以及查询x的第i位在二进制下是0还是1 作为一道noi的题,非常考验写代码综合能力,敲+调+借鉴神犇的代码 3个多小时 ...

  4. loj#2312. 「HAOI2017」八纵八横(线性基 线段树分治)

    题意 题目链接 Sol 线性基+线段树分治板子题.. 调起来有点自闭.. #include<bits/stdc++.h> #define fi first #define se secon ...

  5. 【NOI】2017 整数(BZOJ 4942,LOJ2302) 压位+线段树

    [题目]#2302. 「NOI2017」整数 [题意]有一个整数x,一开始为0.n次操作,加上a*2^b,或询问2^k位是0或1.\(n \leq 10^6,|a| \leq 10^9,0 \leq ...

  6. 【LOJ】#3109. 「TJOI2019」甲苯先生的线段树

    LOJ#3109. 「TJOI2019」甲苯先生的线段树 发现如果枚举路径两边的长度的话,如果根节点的值是$x$,左边走了$l$,右边走了$r$ 肯定答案会是$(2^{l + 1} + 2^{r + ...

  7. LibreOJ2302 - 「NOI2017」整数

    Portal Description 有一个整数\(x=0\),对其进行\(n(n\leq10^6)\)次操作: 给出\(a(|a|\leq10^9),b(b\leq30n)\),将\(x\)加上\( ...

  8. 「NOI2017」整数 解题报告

    「NOI2017」整数 有一些比较简单的\(\log^2n\)做法 比如暴力在动态开点线段树上维护每个位置为\(0\)还是\(1\),我们发现涉及到某一位加上\(1\)或者减去\(1\)实际上对其他位 ...

  9. loj #2305. 「NOI2017」游戏

    #2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...

随机推荐

  1. cts测试流程

    测试目的: 用于检测你做的Android系统是否满足兼容性要求,通俗点说,Google认为Android系统应该满足的条件,你需要满足. 例如框架层暴露给应用层的某些接口,Google认为你因该有,那 ...

  2. 05 | 基础篇:某个应用的CPU使用率居然达到100%,我该怎么办?

    通过前两节对平均负载和 CPU 上下文切换的学习,我相信你对 CPU 的性能已经有了初步了解.不过我还是想问一下,在学这个专栏前,你最常用什么指标来描述系统的 CPU 性能呢?我想你的答案,可能不是平 ...

  3. hash-散列笔记

    散列基础与整数散列 散列(hash哈希)的基本思想--"将元素通过一个函数转换为整数,使该整数可以尽量唯一地代表这个元素".其中把这个转换函数称为散列函数H,元素在转换前为key, ...

  4. 爬虫之requests 请求

    1.发送不同的请求 import requests r = requests.get('https://www.baidu.com/') r = requests.post('http://httpb ...

  5. Node.js实战2:模块使用入门。

    NodeJS有丰富的三方模块,借助这些模块,可以快速的开发各类应用.这使用Nodejs可以进行很便捷.快速的开发. 1.安装与加载模块内核.三方 使用npm可以搜索.安装.卸载模块. 例: 搜索模块 ...

  6. flex布局相关用法

    /* pages/classic/classic.wxss */ .chunk { /* 行内元素可设置但是设置了flex,无效了 *//* display: inline-block; */ wid ...

  7. Oracle-常见的错误

    1.见下面的例子 create or replace procedure p_qr_stu_cid(s_id in number, c_id out number) as begin select t ...

  8. redis学习(二)

    简单了解一下 1.build.gradle中添加 依赖  org.springframework.boot:spring-boot-starter-data-redis //定义依赖:声明项目中需要哪 ...

  9. JavaScript 数组sort方法使用

    直接上例子 1.无参调用返回按unicode字符编码排序 var arr = [1,2,0,21,15,6,34,9,45]; var arrSort = arr.sort(); console.lo ...

  10. elasticsearch索引清理脚本shell

    es-index-clear.sh: #!/bin/bash#----------------------------------------------# Module: es-index-clea ...