看懂了的大佬的题解。(这个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. hdu5087 Revenge of LIS II (dp)

    只要理解了LIS,这道题稍微搞一下就行了. 求LIS(最长上升子序列)有两种方法: 1.O(n^2)的算法:设dp[i]为以a[i]结尾的最长上升子序列的长度.dp[i]最少也得是1,就初始化为1,则 ...

  2. BestCoder Round #18(hdu5105)Math Problem(高中数学)

    最大值无非就是在两个端点或极值点处取得. 我注意讨论了a=0和b=0,却忽略了极值点可能不在L到R的范围内这一问题.被Hack了. #include<iostream> #include& ...

  3. AngularJs出现错误Error: [ng:areq]

    1.没有对应的控制器 2.有控制器但是路径没有配对

  4. 【ASP.NET Web API2】利用HttpClient调用Web API(TODO)

    参照: 在一个空ASP.NET Web项目上创建一个ASP.NET Web API 2.0应用 纯属记录一下遇到的问题: 我们利用HttpClient来调用自宿主方式寄宿的Web API.HttpCl ...

  5. C# 代码注释规范文档

    C# 提供一种机制,使程序员可以使用含有 XML 文本的特殊注释语法为他们的代码编写文档.在源代码文件中,具有某种格式的注释可用于指导某个工具根据这些注释和它们后面的源代码元素生成 XML.使用这类语 ...

  6. 一道SQL的面试题之联想

    一道SQL的面试题之联想 本人工作在一家小型的民营企业,主要从事业务系统的日常维护,二次开发,菜鸟一枚.周五经理准备面试两个开发人员,据简历,都还比较不错,让经理产生了想法,于是准备了一套面试题目,给 ...

  7. MySQL 数据库备份种类以及常用备份工具汇总

    1,数据库备份种类 按照数据库大小备份,有四种类型,分别应用于不同场合,下面简要介绍一下: 1.1完全备份 这是大多数人常用的方式,它可以备份整个数据库,包含用户表.系统表.索引.视图和存储过程等所有 ...

  8. RuPengWang项目

    项目 Day1------------------------- 说明:建外键约束.ashx+Razor RupengWang创建三个类库Model DAL BLL后台:RupengWang.Admi ...

  9. canvas渐变

    代码: 1 /** 2 * Created by Administrator on 2016/1/29. 3 */ 4 function draw(id){ 5 var canvas = docume ...

  10. Oracle 文件

    参数文件 跟踪文件 告警文件 数据文件 临时文件 控制文件 重做日志文件 密码文件 闪回日志 dum文件 数据泵文件 1参数文件 Parameter file:告诉oracle实例在那里可以找到控制文 ...