看懂了的大佬的题解。(这个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. PHP用*号替代姓名除第一个字之外的字符

    /* * 作用:用*号替代姓名除第一个字之外的字符 * 参数: * * * 返回值:string */ function starReplace($name, $num = 0) { if ($num ...

  2. nyoj-78-圈水池(Graham算法求凸包)

    题目链接 /* Name:nyoj-78-圈水池 Copyright: Author: Date: 2018/4/27 9:52:48 Description: Graham求凸包 zyj大佬的模板, ...

  3. VSCode使用正则表达式进行内容替换

    首先描述一下我要达到的目的: 1.源数据: 2.目标数据: 3.使用的正则表达式如下: (id: (\d+),) id: $2, \n order: $2,

  4. BZOJ - 4196 软件包管理器 (树链剖分+dfs序+线段树)

    题目链接 设白色结点为未安装的软件,黑色结点为已安装的软件,则: 安装软件i:输出结点i到根的路径上的白色结点的数量,并把结点i到根的路径染成黑色.复杂度$O(nlog^2n)$ 卸载软件i:输出结点 ...

  5. LeetCode Largest Palindrome Product

    原题链接在这里:https://leetcode.com/problems/largest-palindrome-product/description/ 题目: Find the largest p ...

  6. BZOJ3075,LG3082 [USACO13MAR]项链Necklace

    题意 Bessie the cow has arranged a string of N rocks, each containing a single letter of the alphabet, ...

  7. hadoop-hive学习笔记

    create table hive_1(id string,name string ,gender string)row format delimited fields terminated by ' ...

  8. 调整 WiFi 驱动设置让 WiFi 信号更稳定

    调整 WiFi 驱动设置让 WiFi 信号更稳定 修改 WiFi 驱动中 的设置,将 Power Saving Mode 的值改为 CAM.

  9. 我的ubuntu新系统自动装软件脚本

    装一些常用软件 配一下环境变量 #!/bin/bash #download g++sudo apt-get install g++ -y#download codeblockssudo apt-get ...

  10. 机器学习:SVM(scikit-learn 中的 SVM:LinearSVC)

    一.基础理解 Hard Margin SVM 和 Soft Margin SVM 都是解决线性分类问题,无论是线性可分的问题,还是线性不可分的问题: 和 kNN 算法一样,使用 SVM 算法前,要对数 ...