[BZOJ4942][Noi2017]整数 线段树+压位
用线段树来模拟加减法过程,维护连续一段中是否全为0/1。
因为数字很大,我们60位压一位来处理。
- #include<iostream>
- #include<cstring>
- #include<cstdlib>
- #include<cmath>
- #include<cstdio>
- #include<algorithm>
- #define maxn 505050
- #define base 60
- #define ll long long
- using namespace std;
- inline ll read() {
- ll x=,f=;char ch=getchar();
- for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
- for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
- return x*f;
- }
- ll n,m,S=(1ll<<)-;
- struct Seg {
- int al[];
- ll tag,val;
- }t[maxn*];
- void put(int o,ll tmp) {
- if(tmp!=-) t[o].val=tmp;
- if(tmp==) {t[o].al[]=;t[o].al[]=;t[o].tag=tmp;}
- else if(tmp==S) {t[o].al[]=;t[o].al[]=;t[o].tag=tmp;}
- else {t[o].al[]=t[o].al[]=;t[o].tag=tmp;}
- }
- void pushdown(int o) {
- int ls=o<<,rs=ls+;
- if(t[o].tag!=-) {put(ls,t[o].tag);put(rs,t[o].tag);t[o].tag=-;}
- }
- void pushup(int o) {
- int ls=o<<,rs=ls+;
- t[o].al[]=t[ls].al[]&t[rs].al[];
- t[o].al[]=t[ls].al[]&t[rs].al[];
- }
- void build(int l,int r,int o) {
- t[o].tag=-,t[o].al[]=;t[o].al[]=;t[o].val=;
- if(l==r) return;
- int mid=l+r>>,ls=o<<,rs=ls+;
- build(l,mid,ls);build(mid+,r,rs);
- }
- ll query(int l,int r,int o,int x) {
- if(l==r) return t[o].val;
- pushdown(o);
- int mid=l+r>>,ls=o<<,rs=ls+;
- if(x<=mid) return query(l,mid,ls,x);
- else return query(mid+,r,rs,x);
- pushup(o);
- }
- void change(int l,int r,int o,int L,int R,ll tmp) {
- if(L<=l&&R>=r) {put(o,tmp);return;}
- pushdown(o);
- int mid=l+r>>,ls=o<<,rs=ls+;
- if(L<=mid) change(l,mid,ls,L,R,tmp);
- if(R>mid) change(mid+,r,rs,L,R,tmp);
- pushup(o);
- }
- int find(int l,int r,int o,int pos,int k) {
- if(t[o].al[!k]) return -;
- if(l==r) return l;
- int mid=l+r>>,ls=o<<,rs=ls+;
- pushdown(o);
- if(pos<=mid) {
- ll tmp=find(l,mid,ls,pos,k);
- if(tmp!=-) return tmp;
- }
- return find(mid+,r,rs,pos,k);
- pushup(o);
- }
- void add(int pos,ll ad) {
- ll tmp=query(,n,,pos);change(,n,,pos,pos,(tmp+ad)&S);
- if(tmp+ad>S) {
- int l=find(,n,,pos+,);
- tmp=query(,n,,l);
- change(,n,,l,l,tmp+);
- if(pos+<=l-) change(,n,,pos+,l-,);
- }
- }
- void del(int pos,ll ad) {
- ll tmp=query(,n,,pos);
- if(tmp-ad<) change(,n,,pos,pos,(S+tmp-ad+)&S);
- else change(,n,,pos,pos,(tmp-ad)&S);
- if(tmp-ad<) {
- int l=find(,n,,pos+,);
- tmp=query(,n,,l);
- change(,n,,l,l,tmp-);
- if(pos+<=l-) change(,n,,pos+,l-,S);
- }
- }
- int main() {
- m=read();read();read();read();n=;build(,n,);
- for(int i=;i<=m;i++) {
- int tp=read();
- if(tp==) {
- ll a=read(),b=read();
- if(a>) {
- ll p=b/base,q=b%base;
- ll x=(a<<q)&S;add(p,x);
- a>>=base-q;add(p+,a);
- }
- else {
- a=-a;ll p=b/base,q=b%base;
- ll x=(a<<q)&S;del(p,x);
- a>>=base-q;del(p+,a);
- }
- }
- else {
- ll a=read();
- printf("%lld\n",(query(,n,,a/base)>>(a%base))&);
- }
- }
- }
- /*
- 10 3 1 2
- 1 100 0
- 1 2333 0
- 1 -233 0
- 2 5
- 2 7
- 2 15
- 1 5 15
- 2 15
- 1 -1 12
- 2 15
- */
[BZOJ4942][Noi2017]整数 线段树+压位的更多相关文章
- UOJ #314. 【NOI2017】整数 | 线段树 压位
题目链接 UOJ 134 题解 可爱的电音之王松松松出的题--好妙啊. 首先想一个朴素的做法! 把当前的整数的二进制当作01序列用线段树维护一下(序列的第i位就是整数中位权为\(2^k\)的那一位). ...
- 【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)
[BZOJ4942][Noi2017]整数 题目描述去uoj 题解:如果只有加法,那么直接暴力即可...(因为1的数量最多nlogn个) 先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依 ...
- 2018.10.30 bzoj4942: [Noi2017]整数(线段树压位)
传送门 直接把修改的数拆成logloglog个二进制位一个一个修改是会TLETLETLE的. 因此我们把303030个二进制位压成一位储存在线段树里面. 然后维护区间中最靠左二进制位不为0/1的下标. ...
- 【洛谷3822】[NOI2017] 整数(线段树压位)
题目: 洛谷 3822 分析: 直接按题意模拟,完了. 将每次加 / 减拆成不超过 \(32\) 个对单独一位的加 / 减. 考虑给一个二进制位(下称「当前位」)加 \(1\) 时,如果这一位本来就是 ...
- [Bzoj4942][Noi2017]整数(线段树)
4942: [Noi2017]整数 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 363 Solved: 237[Submit][Status][D ...
- BZOJ4942 NOI2017整数(线段树)
首先把每32位压成一个unsigned int(当然只要压起来能过就行).如果不考虑进/退位的话,每次只要将加/减上去的数拆成两部分直接单点修改就好了.那么考虑如何维护进/退位.可以发现进位的过程其实 ...
- noi2017 T1 整数 ——线段树
loj.ac上有 题目传送门 不过我还是把题目搬过来吧 整数(integer)[题目背景]在人类智慧的山巅,有着一台字长为 1048576 位的超级计算机,著名理论计算机科 学家 P 博士正用它进行 ...
- 【noi2017】 整数 线段树or模拟
ORZYYB 题目大意:你需要维护一个有$3\times 10^7$个二进制位的数,有一种修改方式和一种询问方式 对这个数加上$a\times2^b$,其中$|a|≤10^9$,$b≤3\times ...
- BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流
题目链接: [Noi2017]蔬菜 题目大意:有$n$种蔬菜,每种蔬菜有$c_{i}$个,每种蔬菜每天有$x_{i}$个单位会坏掉(准确来说每天每种蔬菜坏掉的量是$x_{i}-$当天这种蔬菜卖出量), ...
随机推荐
- Adaboost 算法的原理与推导——转载及修改完善
<Adaboost算法的原理与推导>一文为他人所写,原文链接: http://blog.csdn.net/v_july_v/article/details/40718799 另外此文大部分 ...
- js 时间戳 转化
new Date((1524142795*1000)).toJSON().slice(11,16)
- Java基础-synchronized关键字的用法(转载)
synchronized--同步 顾名思义是用于同步互斥的作用的. 这里精简的记一下它的使用方法以及意义: 当synchronized修饰 this或者非静态方法或者是一个实例的时候,所同步的锁是加在 ...
- Sql2008 全文索引创建
在SQL Server 中提供了一种名为全文索引的技术,可以大大提高从长字符串里搜索数 据的速度,不用在用LIKE这样低效率的模糊查询了. 下面简明的介绍如何使用Sql2008 全文索引 一.检查 ...
- oracle,sqlserver,mysql常见数据库jdbc连接
发现JDBC连接字符串总是容易忘记,特此整理一下常用的几种数据的连接 ORACLE: /** * ORACLE * */ public static Connection getOracleConne ...
- OpenCV---图像金字塔原理
图像金字塔原理 (一)图像缩小(先高斯模糊,再降采样,需要一次次重复,不能一次到底) (二)图像扩大(先扩大,再卷积或者使用拉普拉斯金字塔) 图像金字塔介绍 图像金字塔是图像中多尺度表达的一种,最主要 ...
- linux 中 permission denied的问题
想在linux中运行一个脚步,却提示permission denied. 文件权限不允许. 为了获得执行权限,借助chmod指令修改文件权限即可. 1.如果是运行程序时出现此提示,一般执行chmod ...
- 免密码登录服务器python脚本
在自动化运维平台没有做完之前,常需要登录服务器做很多维护操作,每次找好长好长的密码,那么多服务器,你会疯掉的,所以瞎搞了以下脚本.先解一下燃眉之急,哈哈 cat login_root.exp #!/u ...
- git使用(1)----推送代码到远程
git使用(1) 首先要明白git上有三个区域 1.工作区 2.暂存区 3.历史记录区 步骤: 1.git init 2.配置环境(如果配置一次了以后就不用再继续配置) git config - ...
- 源自人脑的神奇算法 -- 读《How to make your own neural network》有感
最近读到了一本很好的关于机器学习-深度学习的书值得推荐下并特意做了这个学习总结. 为什么推荐 在我认为好书(计算机类)的评判有几个标准: 试图以通俗的语言阐述,并在引入任何新概念的时候都讲述来龙去脉, ...