博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[NOI2017]整数
阅读量:6901 次
发布时间:2019-06-27

本文共 990 字,大约阅读时间需要 3 分钟。

减法产生退位,这个十分不好处理,考虑把加的数和减的数分别存在$a,b$

修改就直接把对应位置往后$30$位提出来,做加法,再回去更新,如果产生了进位($31$位),那么暴力更新即可,反正进位次数是均摊$O(1)$

查询时等于是判断$a-b$在第$k$位的值,我们需要知道第$k$位在做减法时是否产生退位,那么只需要比较$a$和$b$的前$k-1$位的大小即可,我们需要找到$a,b$的$k$位以下第一个不等的位,这一步直接用线段树维护$a\text{ xor }b$即可,查询时在线段树上跑就可以了

空间和时间应该都很爆炸,但是能过...

#include
bool x[2][30000100],s[67108864];int M;void pushup(int x){s[x]=s[x<<1]|s[x<<1|1];}void modify(int x){ s[x+=M]^=1; while(x>>=1)pushup(x);}int down(int x){ return x>=M?x-M:(s[x<<1|1]?down(x<<1|1):down(x<<1));}int up(int x){ return x==1?-1:((x&1)&&s[x^1]?down(x^1):up(x>>1));}void add(int a,int b){ int i,f,t,tt; f=0; if(a<0){ a=-a; f=1; } t=0; for(i=b+29;i>=b;i--)t=t*2+x[f][i]; tt=t+a; for(i=b;i<=b+29;i++){ x[f][i]=tt>>(i-b)&1; if((tt>>(i-b)&1)^(t>>(i-b)&1))modify(i); } if(tt>=1<<30){ for(i=b+30;x[f][i];i++){ x[f][i]=0; modify(i); } x[f][i]=1; modify(i); }}int query(int k){ int s,i; s=x[0][k]^x[1][k]; i=up(k+M); if(i!=-1&&x[0][i]

转载于:https://www.cnblogs.com/jefflyy/p/9235804.html

你可能感兴趣的文章
Windows SqlServer 2008服务1433端口不监听问题排查
查看>>
oracle 11g rac安装之oracle database报错解决
查看>>
linux固定用户访问ip限制
查看>>
华为SSH配置
查看>>
比较好用的dns列表
查看>>
linux下mysql的root密码忘记解决方法
查看>>
多机调度问题-贪心算法
查看>>
sql_trace的使用
查看>>
我的友情链接
查看>>
WordPress 禁用自动保存、文章多个版本
查看>>
JDK环境配置
查看>>
修改Linux中的root密码
查看>>
搭建本地yum仓库
查看>>
机器学习:选对时机直线超车
查看>>
Java基础基本常识
查看>>
谈谈Python实战数据可视化之matplotlib模块(实战篇)
查看>>
2.27linux和windows互传文件 3.1 用户配置文件和密码配置文件 3.2 用户组管理
查看>>
Java程序员需要技术能力达到什么程度,才能拿到月薪30k?
查看>>
Java之品优购课程讲义_day14(5)
查看>>
Jenkins 持续集成使用教程
查看>>