用线段树来模拟加减法过程,维护连续一段中是否全为0/1。

因为数字很大,我们60位压一位来处理。

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<cmath>
  5. #include<cstdio>
  6. #include<algorithm>
  7. #define maxn 505050
  8. #define base 60
  9. #define ll long long
  10. using namespace std;
  11. inline ll read() {
  12. ll x=,f=;char ch=getchar();
  13. for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
  14. for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
  15. return x*f;
  16. }
  17. ll n,m,S=(1ll<<)-;
  18. struct Seg {
  19. int al[];
  20. ll tag,val;
  21. }t[maxn*];
  22. void put(int o,ll tmp) {
  23. if(tmp!=-) t[o].val=tmp;
  24. if(tmp==) {t[o].al[]=;t[o].al[]=;t[o].tag=tmp;}
  25. else if(tmp==S) {t[o].al[]=;t[o].al[]=;t[o].tag=tmp;}
  26. else {t[o].al[]=t[o].al[]=;t[o].tag=tmp;}
  27. }
  28. void pushdown(int o) {
  29. int ls=o<<,rs=ls+;
  30. if(t[o].tag!=-) {put(ls,t[o].tag);put(rs,t[o].tag);t[o].tag=-;}
  31. }
  32. void pushup(int o) {
  33. int ls=o<<,rs=ls+;
  34. t[o].al[]=t[ls].al[]&t[rs].al[];
  35. t[o].al[]=t[ls].al[]&t[rs].al[];
  36. }
  37. void build(int l,int r,int o) {
  38. t[o].tag=-,t[o].al[]=;t[o].al[]=;t[o].val=;
  39. if(l==r) return;
  40. int mid=l+r>>,ls=o<<,rs=ls+;
  41. build(l,mid,ls);build(mid+,r,rs);
  42. }
  43. ll query(int l,int r,int o,int x) {
  44. if(l==r) return t[o].val;
  45. pushdown(o);
  46. int mid=l+r>>,ls=o<<,rs=ls+;
  47. if(x<=mid) return query(l,mid,ls,x);
  48. else return query(mid+,r,rs,x);
  49. pushup(o);
  50. }
  51. void change(int l,int r,int o,int L,int R,ll tmp) {
  52. if(L<=l&&R>=r) {put(o,tmp);return;}
  53. pushdown(o);
  54. int mid=l+r>>,ls=o<<,rs=ls+;
  55. if(L<=mid) change(l,mid,ls,L,R,tmp);
  56. if(R>mid) change(mid+,r,rs,L,R,tmp);
  57. pushup(o);
  58. }
  59. int find(int l,int r,int o,int pos,int k) {
  60. if(t[o].al[!k]) return -;
  61. if(l==r) return l;
  62. int mid=l+r>>,ls=o<<,rs=ls+;
  63. pushdown(o);
  64. if(pos<=mid) {
  65. ll tmp=find(l,mid,ls,pos,k);
  66. if(tmp!=-) return tmp;
  67. }
  68. return find(mid+,r,rs,pos,k);
  69. pushup(o);
  70. }
  71. void add(int pos,ll ad) {
  72. ll tmp=query(,n,,pos);change(,n,,pos,pos,(tmp+ad)&S);
  73. if(tmp+ad>S) {
  74. int l=find(,n,,pos+,);
  75. tmp=query(,n,,l);
  76. change(,n,,l,l,tmp+);
  77. if(pos+<=l-) change(,n,,pos+,l-,);
  78. }
  79. }
  80. void del(int pos,ll ad) {
  81. ll tmp=query(,n,,pos);
  82. if(tmp-ad<) change(,n,,pos,pos,(S+tmp-ad+)&S);
  83. else change(,n,,pos,pos,(tmp-ad)&S);
  84. if(tmp-ad<) {
  85. int l=find(,n,,pos+,);
  86. tmp=query(,n,,l);
  87. change(,n,,l,l,tmp-);
  88. if(pos+<=l-) change(,n,,pos+,l-,S);
  89. }
  90. }
  91. int main() {
  92. m=read();read();read();read();n=;build(,n,);
  93. for(int i=;i<=m;i++) {
  94. int tp=read();
  95. if(tp==) {
  96. ll a=read(),b=read();
  97. if(a>) {
  98. ll p=b/base,q=b%base;
  99. ll x=(a<<q)&S;add(p,x);
  100. a>>=base-q;add(p+,a);
  101. }
  102. else {
  103. a=-a;ll p=b/base,q=b%base;
  104. ll x=(a<<q)&S;del(p,x);
  105. a>>=base-q;del(p+,a);
  106. }
  107. }
  108. else {
  109. ll a=read();
  110. printf("%lld\n",(query(,n,,a/base)>>(a%base))&);
  111. }
  112. }
  113. }
  114. /*
  115. 10 3 1 2
  116. 1 100 0
  117. 1 2333 0
  118. 1 -233 0
  119. 2 5
  120. 2 7
  121. 2 15
  122. 1 5 15
  123. 2 15
  124. 1 -1 12
  125. 2 15
  126. */

[BZOJ4942][Noi2017]整数 线段树+压位的更多相关文章

  1. UOJ #314. 【NOI2017】整数 | 线段树 压位

    题目链接 UOJ 134 题解 可爱的电音之王松松松出的题--好妙啊. 首先想一个朴素的做法! 把当前的整数的二进制当作01序列用线段树维护一下(序列的第i位就是整数中位权为\(2^k\)的那一位). ...

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

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

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

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

  4. 【洛谷3822】[NOI2017] 整数(线段树压位)

    题目: 洛谷 3822 分析: 直接按题意模拟,完了. 将每次加 / 减拆成不超过 \(32\) 个对单独一位的加 / 减. 考虑给一个二进制位(下称「当前位」)加 \(1\) 时,如果这一位本来就是 ...

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

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

  6. BZOJ4942 NOI2017整数(线段树)

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

  7. noi2017 T1 整数 ——线段树

    loj.ac上有  题目传送门 不过我还是把题目搬过来吧 整数(integer)[题目背景]在人类智慧的山巅,有着一台字长为 1048576 位的超级计算机,著名理论计算机科 学家 P 博士正用它进行 ...

  8. 【noi2017】 整数 线段树or模拟

    ORZYYB 题目大意:你需要维护一个有$3\times 10^7$个二进制位的数,有一种修改方式和一种询问方式 对这个数加上$a\times2^b$,其中$|a|≤10^9$,$b≤3\times ...

  9. BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流

    题目链接: [Noi2017]蔬菜 题目大意:有$n$种蔬菜,每种蔬菜有$c_{i}$个,每种蔬菜每天有$x_{i}$个单位会坏掉(准确来说每天每种蔬菜坏掉的量是$x_{i}-$当天这种蔬菜卖出量), ...

随机推荐

  1. Adaboost 算法的原理与推导——转载及修改完善

    <Adaboost算法的原理与推导>一文为他人所写,原文链接: http://blog.csdn.net/v_july_v/article/details/40718799 另外此文大部分 ...

  2. js 时间戳 转化

    new Date((1524142795*1000)).toJSON().slice(11,16)

  3. Java基础-synchronized关键字的用法(转载)

    synchronized--同步 顾名思义是用于同步互斥的作用的. 这里精简的记一下它的使用方法以及意义: 当synchronized修饰 this或者非静态方法或者是一个实例的时候,所同步的锁是加在 ...

  4. Sql2008 全文索引创建

    在SQL Server 中提供了一种名为全文索引的技术,可以大大提高从长字符串里搜索数 据的速度,不用在用LIKE这样低效率的模糊查询了.   下面简明的介绍如何使用Sql2008 全文索引 一.检查 ...

  5. oracle,sqlserver,mysql常见数据库jdbc连接

    发现JDBC连接字符串总是容易忘记,特此整理一下常用的几种数据的连接 ORACLE: /** * ORACLE * */ public static Connection getOracleConne ...

  6. OpenCV---图像金字塔原理

    图像金字塔原理 (一)图像缩小(先高斯模糊,再降采样,需要一次次重复,不能一次到底) (二)图像扩大(先扩大,再卷积或者使用拉普拉斯金字塔) 图像金字塔介绍 图像金字塔是图像中多尺度表达的一种,最主要 ...

  7. linux 中 permission denied的问题

    想在linux中运行一个脚步,却提示permission denied. 文件权限不允许. 为了获得执行权限,借助chmod指令修改文件权限即可. 1.如果是运行程序时出现此提示,一般执行chmod ...

  8. 免密码登录服务器python脚本

    在自动化运维平台没有做完之前,常需要登录服务器做很多维护操作,每次找好长好长的密码,那么多服务器,你会疯掉的,所以瞎搞了以下脚本.先解一下燃眉之急,哈哈 cat login_root.exp #!/u ...

  9. git使用(1)----推送代码到远程

    git使用(1) 首先要明白git上有三个区域 1.工作区 2.暂存区 3.历史记录区 步骤: 1.git  init 2.配置环境(如果配置一次了以后就不用再继续配置) git  config  - ...

  10. 源自人脑的神奇算法 -- 读《How to make your own neural network》有感

    最近读到了一本很好的关于机器学习-深度学习的书值得推荐下并特意做了这个学习总结. 为什么推荐 在我认为好书(计算机类)的评判有几个标准: 试图以通俗的语言阐述,并在引入任何新概念的时候都讲述来龙去脉, ...