【BZOJ4942】[NOI2017]整数(分块)
【BZOJ4942】[NOI2017]整数(分块)
题面
题解
暴力就是真正的暴力,直接手动模拟进位就好了。
此时复杂度是模拟的复杂度加上单次询问的\(O(1)\)。
所以我们需要优化的是模拟的复杂度。
首先如果一位位单位加入,这个复杂度是均摊\(O(1)\)的。因为是均摊,所以我们不能支持撤销(即减法操作),所以加法减法必须分开处理。
对于位运算加法我们考虑压位(或者说分块也是一样的啦)
那么加法就很容易处理了,只需要压位之后找到对应的块,然后直接暴力加上去就行了。
这里稍微注意一下进位的细节。
减法类似处理。
那么最后这样子又变的不好查询了。
而查询的方法就是考虑这一位要不要退位。
退位的话就是加法的和减去减法的和,等价于比较两个后缀大小,比较两个后缀大小可以用\(set\)维护哪些块不相同,完全相同的没有必要比,只需要找到第一个不同的块的就行了。
写法上的话,看到洛谷题解里用\(unsigned\ int\)压\(32\)位,这样子就不需要自己手动取模了,挺方便的。
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
#define ui unsigned int
#define MAX 1000100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
ui A[MAX],B[MAX];
int n;
set<int> S;
int main()
{
n=read();read();read();read();
while(n--)
{
int opt=read();
if(opt==1)
{
int a=read(),b=read();
int p=b/32,r=b%32;
if(a>0)
{
ui s0=(ui)a<<r,s1=r?((ui)a>>(32-r)):0;
ui lst=A[p];A[p]+=s0;s1+=(lst>A[p]);
if(A[p]^B[p])S.insert(p);
else if(S.find(p)!=S.end())S.erase(p);
++p;
while(s1)
{
lst=A[p];A[p]+=s1;s1=(lst>A[p]);
if(A[p]^B[p])S.insert(p);
else if(S.find(p)!=S.end())S.erase(p);
++p;
}
}
else
{
a=-a;
ui s0=(ui)a<<r,s1=r?((ui)a>>(32-r)):0;
ui lst=B[p];B[p]+=s0;s1+=(lst>B[p]);
if(A[p]^B[p])S.insert(p);
else if(S.find(p)!=S.end())S.erase(p);
++p;
while(s1)
{
lst=B[p];B[p]+=s1;s1=(lst>B[p]);
if(A[p]^B[p])S.insert(p);
else if(S.find(p)!=S.end())S.erase(p);
++p;
}
}
}
else
{
int a=read();
int p=a/32,r=a%32;
int ans=((A[p]>>r)&1)^((B[p]>>r)&1);
ui va=A[p]&((1<<r)-1),vb=B[p]&((1<<r)-1);
if(va<vb)ans^=1;
else if(va>vb||S.empty()||p<=*S.begin());
else
{
set<int>::iterator it=S.lower_bound(p);--it;
if(A[*it]<B[*it])ans^=1;
}
printf("%d\n",ans);
}
}
return 0;
}
【BZOJ4942】[NOI2017]整数(分块)的更多相关文章
- [Bzoj4942][Noi2017]整数(线段树)
4942: [Noi2017]整数 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 363 Solved: 237[Submit][Status][D ...
- BZOJ.4942.[NOI2017]整数(分块)
BZOJ 洛谷 UOJ 可能是退役之前最后一个BZOJ rank1了? 参考这里. 如果没有减法,对一个二进制数暴力进位,均摊复杂度是\(O(1)\)的(要进\(O(n)\)次位就至少需要\(O(n) ...
- [BZOJ4942] [NOI2017]整数
题目背景 在人类智慧的山巅,有着一台字长为1048576位(此数字与解题无关)的超级计算机,著名理论计算机科 学家P博士正用它进行各种研究.不幸的是,这天台风切断了电力系统,超级计算机 无法工作,而 ...
- BZOJ4942 NOI2017整数(线段树)
首先把每32位压成一个unsigned int(当然只要压起来能过就行).如果不考虑进/退位的话,每次只要将加/减上去的数拆成两部分直接单点修改就好了.那么考虑如何维护进/退位.可以发现进位的过程其实 ...
- 2018.10.30 bzoj4942: [Noi2017]整数(线段树压位)
传送门 直接把修改的数拆成logloglog个二进制位一个一个修改是会TLETLETLE的. 因此我们把303030个二进制位压成一位储存在线段树里面. 然后维护区间中最靠左二进制位不为0/1的下标. ...
- [BZOJ4942][Noi2017]整数 线段树+压位
用线段树来模拟加减法过程,维护连续一段中是否全为0/1. 因为数字很大,我们60位压一位来处理. #include<iostream> #include<cstring> #i ...
- 【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)
[BZOJ4942][Noi2017]整数 题目描述去uoj 题解:如果只有加法,那么直接暴力即可...(因为1的数量最多nlogn个) 先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依 ...
- [NOI2017]整数
[NOI2017]整数 题目大意: \(n(n\le10^6)\)次操作维护一个长度为\(30n\)的二进制整数\(x\),支持以下两种操作: 将这个整数加上\(a\cdot2^b(|a|\le10^ ...
- NOI2017整数
NOI2017 整数 题意: 让你实现两个操作: 1 \(a\) \(b\):将\(x\)加上整数\(a \cdot 2 ^ b\),其中 \(a\)为一个整数,\(b\)为一个非负整数 2 \( ...
随机推荐
- Java执行shell脚本并返回结果两种方法的完整代码
Java执行shell脚本并返回结果两种方法的完整代码 简单的是直接传入String字符串,这种不能执行echo 或者需要调用其他进程的命令(比如调用postfix发送邮件命令就不起作用) 执行复杂的 ...
- QLineEdit默认提示 setPlaceholderText
Setting this property makes the line edit display a grayed-out placeholder text as long as the text( ...
- pandas 之 交叉表-透视表
import numpy as np import pandas as pd 认识 A pivot table is a data summarization tool(数据汇总工具) frequen ...
- Python玩转微信小程序
用Python玩转微信 Python玩转微信 大家每天都在用微信,有没有想过用python来控制我们的微信,不多说,直接上干货! 这个是在 itchat上做的封装 http://itchat. ...
- 三种MPM在工作时的属性
l prefork:域fork,一个进程一个请求 l worker:一个线程一个请求,一个进程生成多个线程 l event:事件模型,单线程响应多个请求,基于事件驱动 在主配置文件当中,在htt ...
- MySQL 5.5/5.6/5.7及以上版本安装包安装时如何选择安装路径
安装环境需求: 自从昨天安装了mysql 5.7,发现了一个问题,mysql5.6起,已经不支持2003系统了,如果安装了无法开启服务而且会出现在 本地计算机 无法启动 MySQL57 服务.错误 1 ...
- JDOJ 2254 Who am I?
JDOJ 2254: Who am I? Description 输出程序自己本身的源代码. Input 无 Output 输出程序自己本身的源代码. 我真是搞不懂了出这道题还把它归到程序语法基础题里 ...
- 团队冲刺---Four
今天的计划: 研究css模板. 昨天做了什么: 寻找css模板,研究界面布局. 遇到的问题: css模板,代码看不太懂,好多标签都不会用.
- luoguP1829 [国家集训队]Crash的数字表格 / JZPTAB(莫比乌斯反演)
题意 注:默认\(n\leqslant m\). 所求即为:\(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}lcm(i,j)\) 因为\(i*j=\gcd(i, ...
- 生产者消费者模型-Java代码实现
什么是生产者-消费者模式 比如有两个进程A和B,它们共享一个固定大小的缓冲区,A进程产生数据放入缓冲区,B进程从缓冲区中取出数据进行计算,那么这里其实就是一个生产者和消费者的模式,A相当于生产者,B相 ...