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? ...
随机推荐
- iOS开发者知识普及,Swift 挑战 Objective-C,谁会笑到最后?
前言: 目前全球共有超过 7 亿台 iPhone 处于活跃状态,全球约有2000万名 iOS 开发者,这造就了 iOS 作为全球第二大移动设备平台的状态. 虽然安卓系统的全球市场占有率超过 iOS 系 ...
- SpringCloud笔记四:Ribbon
目录 什么是Ribbon? Ribbon的配置 Maven引入 开启注解 Ribbon负载均衡 新建provider8002和8003 Ribbon核心组件IRule Ribbon自定义 什么是Rib ...
- https://www.chromestatus.com/features/5093566007214080
移动端滑动报错:Unable to preventDefault inside passive event listener due to target being treated as passiv ...
- 2018-2019-2 《Java程序设计》第5周学习总结
20175319 2018-2019-2 <Java程序设计>第5周学习总结 教材学习内容总结 本周学习<Java程序设计>第六章: 接口 实现接口 接口的UML图 接口回调 ...
- 关于java集合的练习
关于java集合的练习 练习一:Collection集合练习 一.产生10个1-100的随机数,并放到一个数组中,把数组中大于等于10的数字放到一个list集合中,并打印到控制台. public cl ...
- 牛牛与数组 (简单dp)
题目链接 这种题一看就是dp啊,dp[i][j]表示第i位放j的方案数,转移方程为dp[i][j]=dp[i-1][k]{k<=i||k%i!=0},当然我们可以三层循环来找,但数据显然会超时, ...
- PhpStorm+xdebug调试——更新
之前写过一篇<PhpStorm+xdebug+postman调试>,但是经过后来一段时间的使用,发现有些累赘.这里介绍一种比较简单方便的操作. 在上一篇文章中有一段“ 7.设置Server ...
- 通过IDEA搭建scala开发环境开发spark应用程序
一.idea社区版安装scala插件 因为idea默认不支持scala开发环境,所以当需要使用idea搭建scala开发环境时,首先需要安装scala插件,具体安装办法如下. 1.打开idea,点击c ...
- Notepad++崩溃后文件内容找不到问题
也许是因为Ctrl + s 摁太多太频繁,一不小心Notepad++崩溃了 重启后发现原来的文件还在,但是文件内容全部都被清空了 我没有手动备份这个文件, 如何找回??? 点击设置,首选项,里面有个备 ...
- SpringBatch框架简介
概观 轻量级,全面的批处理框架,旨在开发对企业系统日常运营至关重要的强大批处理应用程序. Spring Batch提供了可重复使用的功能,这些功能对于处理大量记录至关重要,包括记录/跟踪,事务管理,作 ...