看懂了的大佬的题解。(这个id太巨了,找不到他的blog)

考虑直接暴力算进位均摊复杂度是对的,证明戳这里

但是题目要求我们支持一个减操作,这就相当于返回之前操作前的结果,这对于这种均摊的复杂度的东西来说简直是不可能的,分分钟$T$飞。

解决方法也很简单:对加减分别维护一个绝对值,询问的时候相减就好了,这样复杂度也是对的。

然后考虑询问:因为询问的时候要比较两个绝对值的大小,考虑一下向前面借位的情况, 然后就相当于找一找第$b$位之后的为$1$的位哪个先,这个过程只要在暴力的时候维护一个$set$就可以解决了。

然后考虑压一下位,这时候就从dalao那里学到了很神奇的$unsigned int$刚好用这玩意压$32$位。

这个东西有一个好处,就是自动溢出取模,那么加法的时候只要维护一个$tag$,看一下原来的数加上之后是不是比原来小,就可以判断是否有进位了。

注意到修改和查询的时候其实可能有不完整的块,所以先分别处理一下。

时间复杂度$O(nlogn)$。

Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
typedef unsigned int uint; const int N = 1e6 + ; int qn;
uint inc[N], dec[N];
set <int> s; template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for(; ch > ''|| ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} int main() {
int op;
read(qn), read(op), read(op), read(op);
for(int a, b; qn--; ) {
read(op);
if(op == ) {
read(a), read(b);
int p = (uint)b / , q = (uint)b % ;
if(a > ) {
uint add = (uint)a << q, tag = (uint)a >> ( - q); tag >>= ;
uint old = inc[p]; inc[p] += add, tag += (old > inc[p]);
if(inc[p] ^ dec[p]) s.insert(p);
else if(s.count(p)) s.erase(p);
for(++p; tag != ; ++p) {
old = inc[p], inc[p] += tag, tag = (old > inc[p]);
if(inc[p] ^ dec[p]) s.insert(p);
else if(s.count(p)) s.erase(p);
}
} else {
a = -a;
uint add = (uint)a << q, tag = (uint)a >> ( - q); tag >>= ;
uint old = dec[p]; dec[p] += add, tag += (old > dec[p]);
if(inc[p] ^ dec[p]) s.insert(p);
else if(s.count(p)) s.erase(p);
for(++p; tag != ; ++p) {
old = dec[p], dec[p] += tag, tag = (old > dec[p]);
if(inc[p] ^ dec[p]) s.insert(p);
else if(s.count(p)) s.erase(p);
}
}
} else {
read(b);
int p = b / , q = b % , ans = (((inc[p] >> q) ^ (dec[p] >> q)) & );
int v1 = inc[p] % ( << q), v2 = dec[p] % ( << q);
if(v1 < v2) printf("%d\n", ans ^ );
else if(v1 > v2 || s.empty() || p <= (*s.begin())) printf("%d\n", ans);
else {
set <int> :: iterator it = s.lower_bound(p); --it;
if(inc[*it] > dec[*it]) printf("%d\n", ans);
else printf("%d\n", ans ^ );
}
}
}
return ;
}

Luogu 3822 [NOI2017]整数的更多相关文章

  1. 洛谷3822 [NOI2017] 整数 【线段树】【位运算】

    题目分析: 首先这题的询问和位(bit)有关,不难想到是用线段树维护位运算. 现在我们压32位再来看这道题. 对于一个加法操作,它的添加位置可以得到,剩下的就是做不超过32的位移.这样根据压位的理论. ...

  2. [NOI2017]整数

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

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

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

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

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

  5. NOI2017整数

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

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

    [BZOJ4942][NOI2017]整数(分块) 题面 BZOJ 洛谷 题解 暴力就是真正的暴力,直接手动模拟进位就好了. 此时复杂度是模拟的复杂度加上单次询问的\(O(1)\). 所以我们需要优化 ...

  7. [Luogu P3825] [NOI2017] 游戏 (2-SAT)

    [Luogu P3825] [NOI2017] 游戏 (2-SAT) 题面 题面较长,略 分析 看到这些约束,应该想到这是类似2-SAT的问题.但是x地图很麻烦,因为k-SAT问题在k>2的时候 ...

  8. 【洛谷3822】[NOI2017] 整数(线段树压位)

    题目: 洛谷 3822 分析: 直接按题意模拟,完了. 将每次加 / 减拆成不超过 \(32\) 个对单独一位的加 / 减. 考虑给一个二进制位(下称「当前位」)加 \(1\) 时,如果这一位本来就是 ...

  9. 【bzoj4942】[Noi2017]整数 压位+线段树

    题目描述 P 博士将他的计算任务抽象为对一个整数的操作. 具体来说,有一个整数 $x$ ,一开始为0. 接下来有 $n$ 个操作,每个操作都是以下两种类型中的一种: 1 a b :将 $x$ 加上整数 ...

随机推荐

  1. MySQL管理

    http://www.yiibai.com/mysql/administration.html 在本节中,您将学习有关MySQL管理教程,包括MySQL服务器启动和关闭,MySQL服务器安全性,MyS ...

  2. xdebug的安装测试

    1.下载 php -version PHP 7.2.0 (cli) (built: Dec 7 2017 23:07:46) ( NTS DEBUG ) 如果PHP版本是7.2以上的必须要下载Xdeb ...

  3. 树莓派相机操作 —— luvcview 的安装、raspistill:摄像头命令

    MMAL (Multimedia Abstraction Layer) RaspiCam Documentation 0. lucview 的安装 安装命令:sudo apt-get install ...

  4. SQL夯实基础(一):inner join、outer join和cross join的区别

    一.数据构建 先建表,再说话 create database Test use Test create table A ( AID ,) primary key, name ), age int ) ...

  5. [SPOJ10707]Count on a tree II

    luogu 题意 给定一个n个节点的树,每个节点表示一个整数,问u到v的路径上有多少个不同的整数. sol 也就是路径数颜色.树上莫队板子题. 我这种分块的姿势貌似是假的. 所以跑的是最慢的QAQ. ...

  6. C# 单例模式代码

    原文地址:http://blog.jobbole.com/101746/ 代码一: public sealed class Singleton     {         static Singlet ...

  7. GUI练习中

    总结:JFrame和Frame是有很大差别的. 不要混淆.否则方法是不能成功调用的 特别是背景色:JFrame.对象f在main里无法调用背景色前景色都不想显示 一下是书上的一段代码,编译错误,但是可 ...

  8. 2018年长沙理工大学第十三届程序设计竞赛 E小木乃伊到我家(spfa模版)

    链接:https://www.nowcoder.com/acm/contest/96/E来源:牛客网 小木乃伊到我家 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他 ...

  9. XXXAction-validation.xml文件中报错:Referenced file Contains errors

    我们需要引用与验证器配置相关的dtd文件,这个文件可以在xwork-core-2.3.1.2.jar下找到(xwork-validator-1.0.3.dtd) 网上有很多处理办法,如下所示: 1.直 ...

  10. Oracle 内存结构

     内存结构 Oracle内存,进程与数据库的图 sga:系统全局区,用来存放操作的数据,库缓存,数据字典等控制信息的内存区域, pga:进程全局区,服务进程专用的内存区域,大多数内容非共享 uga:用 ...