【BZOJ4942】[NOI2017]整数(分块)

题面

BZOJ

洛谷

题解

暴力就是真正的暴力,直接手动模拟进位就好了。

此时复杂度是模拟的复杂度加上单次询问的\(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]整数(分块)的更多相关文章

  1. [Bzoj4942][Noi2017]整数(线段树)

    4942: [Noi2017]整数 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 363  Solved: 237[Submit][Status][D ...

  2. BZOJ.4942.[NOI2017]整数(分块)

    BZOJ 洛谷 UOJ 可能是退役之前最后一个BZOJ rank1了? 参考这里. 如果没有减法,对一个二进制数暴力进位,均摊复杂度是\(O(1)\)的(要进\(O(n)\)次位就至少需要\(O(n) ...

  3. [BZOJ4942] [NOI2017]整数

    题目背景 在人类智慧的山巅,有着一台字长为1048576位(此数字与解题无关)的超级计算机,著名理论计算机科 学家P博士正用它进行各种研究.不幸的是,这天台风切断了电力系统,超级计算机 无法工作,而 ...

  4. BZOJ4942 NOI2017整数(线段树)

    首先把每32位压成一个unsigned int(当然只要压起来能过就行).如果不考虑进/退位的话,每次只要将加/减上去的数拆成两部分直接单点修改就好了.那么考虑如何维护进/退位.可以发现进位的过程其实 ...

  5. 2018.10.30 bzoj4942: [Noi2017]整数(线段树压位)

    传送门 直接把修改的数拆成logloglog个二进制位一个一个修改是会TLETLETLE的. 因此我们把303030个二进制位压成一位储存在线段树里面. 然后维护区间中最靠左二进制位不为0/1的下标. ...

  6. [BZOJ4942][Noi2017]整数 线段树+压位

    用线段树来模拟加减法过程,维护连续一段中是否全为0/1. 因为数字很大,我们60位压一位来处理. #include<iostream> #include<cstring> #i ...

  7. 【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)

    [BZOJ4942][Noi2017]整数 题目描述去uoj 题解:如果只有加法,那么直接暴力即可...(因为1的数量最多nlogn个) 先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依 ...

  8. [NOI2017]整数

    [NOI2017]整数 题目大意: \(n(n\le10^6)\)次操作维护一个长度为\(30n\)的二进制整数\(x\),支持以下两种操作: 将这个整数加上\(a\cdot2^b(|a|\le10^ ...

  9. NOI2017整数

    NOI2017 整数 题意: ​ 让你实现两个操作: 1 \(a\) \(b\):将\(x\)加上整数\(a \cdot 2 ^ b\),其中 \(a\)为一个整数,\(b\)为一个非负整数 2 \( ...

随机推荐

  1. 使用qwt作曲线图——有网格线背景的画法

    创建自己的QwtPlot (1)     增加一个类比如curvePlotWidget,继承自QwtPlot (2)代码示例 curvePlotWidget::curvePlotWidget(QWid ...

  2. python关于 微型微服务框架bottle实践

    代码实践 资源接口类MyWeb.py,定义了资源接口,代码时python2的代码,和3语法略有不同! # coding: utf-8 import json import logging import ...

  3. vue学习指南:第七篇(详细) - Vue的 组件通信

    Vue 的 父传子 子传父 一.父组件向子组件传值: 父传子 把需要的数据 传递给 子组件,以数据绑定(v-bind)的形式,传递到子组件内部,供子组件使用  缩写是(:) 1.创建子组件,在src/ ...

  4. Selenium通过监听事件实现自动截图

    需要继承extends TestListenerAdapter这个类 代码如下package com.mushishi.selenium.util; import java.util.ArrayLis ...

  5. sqlmap 注入的方法及技巧

    sqlmap 注入的方法及技巧 当给 sqlmap 这么一个 url 的时候,它会: 1.判断可注入的参数 2.判断可以用那种 SQL 注入技术来注入 3.识别出哪种数据库 4.根据用户选择,读取哪些 ...

  6. 服务器Oracle数据库配置与客户端访问数据库的一系列必要设置

    tips:所有路径请对应好自己电脑的具体文件路径. 一.服务器及Oracle数据库设置 1.刚装完的Oracle数据库中只有一个dba账户,首先需要创建一个用户. 2.配置监听,C:\app\Admi ...

  7. Linux 用epoll实现的简单http服务器

    Linux 用epoll实现的简单http服务器 main.c #include <stdio.h> #include <sys/types.h> #include <s ...

  8. XGBoost和LightGBM的参数以及调参

    一.XGBoost参数解释 XGBoost的参数一共分为三类: 通用参数:宏观函数控制. Booster参数:控制每一步的booster(tree/regression).booster参数一般可以调 ...

  9. JS高阶---事件循环模式(事件轮询)

    大纲: 相关知识点: 主体: (1)模型原理 JS部分:初始化代码执行 WebAPIS:执行上下文对象(不是一个真的对象,而是一个抽象的虚拟对象,可以看做栈里的一个区域,包含很多对象) setTime ...

  10. 构建根文件系统之busybox

    配置busybox 首先将busybox的压缩包放入服务器进行解压缩: busybox集合了几百个命令,在一般的系统中并不需要全部使用.可以通过配置busybox来选择这些命令.定制某些命令的功能(选 ...