BZOJ.4942.[NOI2017]整数(分块)
可能是退役之前最后一个BZOJ rank1了?
参考这里。
如果没有减法,对一个二进制数暴力进位,均摊复杂度是\(O(1)\)的(要进\(O(n)\)次位就至少需要\(O(n)\)次操作)。
但是这题有减法...显然暴力进位就不对了。
那么我们把减法变成加法,分别维护加上的数\(inc\)和减掉的数\(dec\)是多大。查询时显然不能直接两位相减,要判断一下后面是否需要进位。
对此用\(set\)维护一下\(inc,dec\)所有不同位的位置,找到查询位后面第一个不同的位置,判一下大小关系就可以了。
关于维护进位,比较显然的是拿线段树维护每一位的情况,把\(a\times2^b\)拆成\((2^{a_1}+2^{a_2}+...)2^n\)。。这样就成两个\(\log\)了(╯‵□′)╯︵┻━┻。
注意到\(a\)不算大,而且线段树的每个位置是可以表示\(16\)或\(32\)位的。直接把\(a\)左移\(b\)位(本来就是= =),也就是把\(a\)加到\(b\)那个位置即可。如果取\(32\)位这么加一次显然是只会进位一次的(最多影响两个位置)。
(\(32\)位可以直接用unsigned int,自然溢出就可以得到加之后这几位的值,判断是否进位就判一下这个数加之前与加之后的大小关系即可)
注意到这个线段树其实没什么必要。分块,每块维护\(32\)位的值,每次只要在对应块上加,然后暴力进位即可。
复杂度\(O(n\log n)\)(set...)。
另外移位不能\(\geq\)位宽,所以移\(32\)位拆成移\(31\)位再移\(1\)位好了。。
//18148kb 3740ms
#include <set>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define pc putchar
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
typedef unsigned int uint;
const int N=1e6+5;
uint inc[N],dec[N];
std::set<int> st;
char IN[MAXIN],*SS=IN,*TT=IN,OUT[N<<1],*O=OUT;
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now*f;
}
void Modify(uint a,uint b,uint *A,uint *B)//a在传参前就要取abs啊(uint)
{//2^5=32
int p=b>>5,q=b&31;
uint tmp=A[p],delta=(a>>31-q)>>1; A[p]+=(a<<q);//uint
delta+=(A[p]<tmp); std::set<int>::iterator it;
if(A[p]!=B[p]) st.insert(p);
else if((it=st.find(p))!=st.end()) st.erase(it);
while(delta)
{
tmp=A[++p], A[p]+=delta, delta=A[p]<tmp;
if(A[p]!=B[p]) st.insert(p);
else if((it=st.find(p))!=st.end()) st.erase(it);
}
}
void Query()
{
int b=read(),p=b>>5,q=b&31,ans=((inc[p]^dec[p])>>q)&1;
uint v1=inc[p]&((1<<q)-1),v2=dec[p]&((1<<q)-1);//inc[p]%(2^q) 取出该块p后面的部分
if(v1<v2) *O++=((ans^1)+48);//借位
else if(v1>v2||/*st.empty()||*/*st.begin()>=p) *O++=(ans+48);
else
{
std::set<int>::iterator it=st.lower_bound(p); --it;
*O++=((inc[*it]>dec[*it]?ans:ans^1)+48);
}
*O++='\n';
}
int main()
{
st.insert(N);
for(int T=read(),a=(read(),read(),read()),b; T--; )
switch(read())
{
case 1: a=read(),b=read(),Modify(a>0?a:-a,b,a>0?inc:dec,a>0?dec:inc); break;
case 2: Query();
}
fwrite(OUT,1,O-OUT,stdout);
return 0;
}
BZOJ.4942.[NOI2017]整数(分块)的更多相关文章
- BZOJ 4942 NOI2017 整数 (压位+线段树)
题目大意:让你维护一个数x(x位数<=3*1e7),要支持加/减a*2^b,以及查询x的第i位在二进制下是0还是1 作为一道noi的题,非常考验写代码综合能力,敲+调+借鉴神犇的代码 3个多小时 ...
- bzoj 4942: [Noi2017]整数
Description Solution 加法减法可以分开考虑,如果只有加法的话,直接暴力进位复杂度是对的 询问的时候就是把两个二进制数做差,判断第 \(k\) 位的取值 实际上我们只需要判断 \(1 ...
- [Bzoj4942][Noi2017]整数(线段树)
4942: [Noi2017]整数 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 363 Solved: 237[Submit][Status][D ...
- 【BZOJ4942】[NOI2017]整数(分块)
[BZOJ4942][NOI2017]整数(分块) 题面 BZOJ 洛谷 题解 暴力就是真正的暴力,直接手动模拟进位就好了. 此时复杂度是模拟的复杂度加上单次询问的\(O(1)\). 所以我们需要优化 ...
- [NOI2017]整数
[NOI2017]整数 题目大意: \(n(n\le10^6)\)次操作维护一个长度为\(30n\)的二进制整数\(x\),支持以下两种操作: 将这个整数加上\(a\cdot2^b(|a|\le10^ ...
- 【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)
[BZOJ4942][Noi2017]整数 题目描述去uoj 题解:如果只有加法,那么直接暴力即可...(因为1的数量最多nlogn个) 先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依 ...
- NOI2017整数
NOI2017 整数 题意: 让你实现两个操作: 1 \(a\) \(b\):将\(x\)加上整数\(a \cdot 2 ^ b\),其中 \(a\)为一个整数,\(b\)为一个非负整数 2 \( ...
- 【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 ...
- BZOJ 2120: 数颜色 分块
2120: 数颜色 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php? ...
随机推荐
- jmeter+maven+jenkins自动化接口测试(上)
代码已上传git(包括调试的jmx,jmeter相关文件等):https://gitlab.com/yinzhenzhi/jmeterandmaven 目的:现在很多人都在做自动化接口的平台,我也正在 ...
- 关于confluence上传文件附件预览查看时出现乱码的问题解决办法
在confluence上传excel文件,预览时发现乱码问题主要是因为再上传文件的时候一般是Windows下的文件上传,而预览的时候,是linux下的环境,由于linux下没有微软字体,所以预览的时候 ...
- Centos 7最小化部署apollo
https://github.com/nobodyiam/apollo-build-scripts
- openstack项目【day23】:keystone组件网关协议
本节内容 一 静态页面和动态页面 二 什么是web server 三 什么是网关协议 3.1 引子 3.2 网关协议 四 网关协议CGI.FastCGI.WSGI.UWSGI 五 网关协议与keyst ...
- SpringBoot系列: Web应用鉴权思路
==============================web 项目鉴权============================== 主要的鉴权方式有:1. 用户名/密码鉴权, 然后通过 Sess ...
- [物理学与PDEs]第2章第2节 粘性流体力学方程组 2.3 广义 Newton 法则---本构方程
1. ${\bf P}=(p_{ij})$, 而 $$\bex p_{ij}=-p\delta_{ij}+\tau_{ij}, \eex$$ 其中 $\tau_{ij}$ 对应于摩擦切应力. 2. ...
- 【codeforces 914H】Ember and Storm's Tree Game
原题链接 Description Ember和Storm正在玩游戏.首先,Ember构造一棵n个节点且每个节点度数不超过d的带节点编号的树T.然后,Storm选择两个不同的节点u和v,并写下从u到v路 ...
- 🍓 移动端调试工具之vconsole的使用~ 🍓
这里以在vue项目中的使用为例⬇️ 嗯模块化的. 不消多说,先cnpm install vconsole -S 然后在mian.js中配置之- ok啦-- 开发混合app的筒子,使用mac的话也有别的 ...
- 【原创】Linux基础之常用命令
1 磁盘.cpu.内存相关 查看全部设备信息 # lspci 查看整体磁盘空间占用情况 # df -h 查看整体磁盘inode占用情况 # df -i 查看文件详细信息 # ls -l $path 查 ...
- Python-Django-常用字段和参数
-1 表模型如果不写主键,orm会自动创建一个主键 -2 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名 ...