DS
树状数组
原始问题
- \(a_x \overset+\gets y\)
- \(\sum\limits_{i=1}^{r} a_i\)
解决方法:
定义 \({\rm lb}(i) = i-i \wedge (i-1)\)
定义 \(f(i) = i \wedge (i-1)\),\(f(0)=0\)。
可以发现 \(f^{\left\lfloor(\log_2 n+1)\right\rfloor}(n)=0\)。
另外地,\(\log_2 {\rm lb}(x)\) 正好是 \(x\) 的二进制表示 \(\sum\limits^{\infty}_{i=0}k_i2^i\) 的从右往左的第一个零的位置(最低位是 \(0\) 位),或者说 \({\rm lb}(x) = 2^{\min\{i \in \mathbf N \mid k_i=1\}}\)。
因此 \({\rm lb}(2^\lambda) = 2^\lambda(\lambda \in \mathbf N)\)。
考虑利用 \({\rm lb}\) 和 \(f\) 函数进行操作,将 \(1 \sim r\) 划分为 \(\le \log_2 n+1\) 的区间。
考虑化为 \((f(n),n]\),可以通过一个数组 \(b\) 解决。
令 \(q\) 为前缀和数组,显然有 \(q_n = q_{f(n)} + b_n\)。
我们考虑修改操作,相当于解一个方程组 \(f(x) \le n\),因为 \(f(x) = x - {\rm lb}(x)\),所以 \(x - {\rm lb}(x) \le n \Longrightarrow {\rm lb}(x) \ge x-n\),考虑枚举 \({\rm lb}(x) = r\),可以发现满足条件的 \(x\) 最多只有一个:\(x = \left\lceil \dfrac n r\right\rceil r\),但是有时求解出的 \({\rm lb}(x) \ne r\),这时候说明 \({\rm lb}(n) > r\),此时没有满足条件的解。
由于 \(f^{\left\lfloor(\log_2 n+1)\right\rfloor}(n)=0\),所以统计一次前缀和的复杂度为 \(O(\log L)\)(L 为数组长度,下同),又因为对于每个 \({\rm lb}(x)\) 最多只有一个 \(x\),而且 \({\rm lb}(x) = 2^\lambda(\lambda \in \mathbf N)\),所以最多只有 \(\left\lfloor\log_2 L+1\right\rfloor\) 个解,所以单点修改的复杂度为 \(O(\log n)\),完毕。
给出伪代码:
Variables:
T: Array[Int] // 树状数组变量
L: Int // 大小
Functions:
f(x: Int) -> Int = x & (x-1)
lb(x: Int) -> Int = x - f(x)
Query(ind: Int) -> Int = ans: // 查询前缀和
ans = 0
while ind != 0
ans = ans + T[ind]
ind = f(ind)
Modify(ind: Int, val: Int) -> Null:
t: Int = 1
while t <= L
x: Int = ceil(ind/t)*t
if lb(x) == t
T[x] = T[x] + val
t = 2t
树状数组的 modify 有一种等价写法:
Modify(ind: Int, val: Int) -> Null:
while ind <= L
T[ind] = T[ind] + val
ind = ind + lb(ind)
这个方法我暂时没有找到严格的数学证明,这里给一张图。
(贺的)
前缀修改,单点查询
- \(\forall i \in [1, R],a_i \overset+\gets y\)
- \(a_x\)
通过差分,可以轻松解决。
multiset 个数查询
- 删除一个 \([1, R]\)
- 加入一个 \([1, R]\)
- 求 \(x\) 在集合中出现了多少次
建立一个桶数组,删除就是 \(\forall i \in [1, R],a_i \overset-\gets 1\),加入就是 \(\forall i \in [1, R],a_i \overset+\gets 1\),于是转化为前缀修改,单点查询。有时需要离散化。这种方法叫做 权值树状数组。
动态 multiset 第 \(K\) 小
- 加入一个 \(x\)
- 删除一个 \(x\)
- 求集合第 \(K\) 小
考虑权值树状数组,12 操作显然,3 操作可以直接二分,查询从 \(0 \sim x\) 的个数,转化为单点修改,前缀查询,注意,\(3\) 操作的时间复杂度为 \(O(\log^2 L)\)
二维偏序
考虑逆序对问题:建立权值树状数组,每次先插入 \(a_i\),然后查询 \((a_i,\max a]\) 的个数(因为此时进这个集合的一定下标 \(\le i\),而且 \(a_i \not> a_i\),所以是 \(i<j \wedge a_i>a_j\) 的个数),通过建立第一维的顺序可以求二维偏序。
前缀修改,前缀查询
- \(\forall i \in [1, R],a_i \overset+\gets y\)
- \(\sum\limits_{i=1}^{r} a_i\)
考虑差分。题目变为
- \(a_i \overset+\gets y\)
- \(\sum\limits^{R}_{i=1}\sum\limits^{i}_{j=1} a_j=\sum\limits^{R}_{i=1} (R-i+1)a_i=\sum\limits^{R}_{i=1} Ra_i-ia_i+a_i=(R+1)\sum\limits^{R}_{i=1}a_i-\sum\limits^{R}_{i=1}ia_i\)
考虑维护两个树状数组,分别维护 \(a_i\) 和 \(ia_i\),即可解决。
PM+PPQ
- \(\forall i \in [1, R],a_i \overset+\gets y\)
- \(\sum\limits_{i=1}^{r} \sum\limits_{j=1}^{i} a_j\)
考虑差分。题目变为
- \(a_i \overset+\gets y\)
- \(\sum\limits^{R}_{i=1}\sum\limits^{i}_{j=1}\sum\limits^{j}_{k=1} a_k=\sum\limits^{R}_{i=1}(i\sum\limits^{i}_{j=1}a_j)+\sum\limits^{R}_{i=1}(\sum\limits^{i}_{j=1}a_j)-\sum\limits^{R}_{i=1}\sum\limits^{i}_{j=1}ja_j-\text{Lazy,懒得退了,反正里面是一个多项式}\)
DS的更多相关文章
- 创建Azure DS 虚拟机并附加SSD硬盘
$subscriptionName = "Windows Azure Enterprise Trial" #订阅名称 $location = "China East&qu ...
- DS实验题 融合软泥怪-2 Heap实现
题目和STL实现:DS实验题 融合软泥怪-1 用堆实现优先队列 引言和堆的介绍摘自:Priority Queue(Heaps)--优先队列(堆) 引言: 优先队列是一个至少能够提供插入(Insert) ...
- Hyper-V 2012 R2 故障转移群集之建立域控(AD DS)与加入域
Windows 2012 R2建立域控(AD DS)与加入域 Active Directory概述: 使用 Active Directory(R) 域服务 (AD DS) 服务器角 ...
- dataGridViewX和数据库的链接之dataGridViewX1.DataSource = ds.Tables[0];
dataGridViewX1.DataSource = ds.Tables[0]; 1, dataGridViewX和数据库链接,如果我们用 dataGridViewX1.DataSource = d ...
- Windows Azure Virtual Machine (26) 使用高级存储(SSD)和DS系列VM
<Windows Azure Platform 系列文章目录> Update: 2016-11-3,如果大家在使用Linux VM,使用FIO进行IOPS测试的时候,请使用以下命令: su ...
- DS Tree 已知后序、中序 => 建树 => 求先序
注意点: 和上一篇的DS Tree 已知先序.中序 => 建树 => 求后序差不多,注意的地方是在aftorder中找根节点的时候,是从右往左找,因此递归的时候注意参数,最好是拿纸和笔模拟 ...
- [DS Basics] Data structures
1, LinkedList composed of one and one Node: [data][next]. [head] -> [data][next] -> [data][nex ...
- DS实验题 Old_Driver UnionFindSet结构 指针实现邻接表存储
题目见前文:DS实验题 Old_Driver UnionFindSet结构 这里使用邻接表存储敌人之间的关系,邻接表用指针实现: // // main.cpp // Old_Driver3 // // ...
- DS实验题 Dijkstra算法
参考:Dijkstra算法 数据结构来到了图论这一章节,网络中的路由算法基本都和图论相关.于是在拿到DS的实验题的时候,决定看下久负盛名的Dijkstra算法. Dijkstra的经典应用是开放最短路 ...
- XLAT转码:以DS:【BX+AL】为地址,提取存储器中的一个字节再送入AL
data segment a db ,,,,,,,, b dw ;sum of a table db 11h,22h,33h,44h,55h,66h,77h,88h,99h ends code seg ...
随机推荐
- opencv-python保存视频
import cv2 class WVideoManager: def __init__(self, write_path: str, width: int, height: int, FPS: in ...
- easyui combobox重复渲染问题
当一个页面有两个easyui combobox存在时,并且同时给两个combobox赋相同值,某些easyui的版本会导致其中一个无法切换选项. 解决办法,分两步赋值,可解决问题
- Could not transfer artifact xxx from/to xxx解决方案
maven中默认的镜像加载是这个 在setting.xml文件中 <mirror> <id>nexus</id> <mirrorOf>*</mir ...
- gitlab和jenkins做持续集成构建教程
背景介绍 上一个轮回,我花了三篇文章的时间着重向大家介绍了在条件有限的情况下,如果优雅地进行前端发版和迭代.庆七一,热烈庆祝香港回归,人民生活水平越来越好,昨天上午我自掏腰包买了台服务器,决定由冷兵器 ...
- NC19916 [CQOI2010]扑克牌
NC19916 [CQOI2010]扑克牌 题目 题目描述 你有n种牌,第i种牌的数目为 \(c_i\) .另外有一种特殊的牌:joker,它的数目是m.你可以用每种牌各一张来组成一套牌,也可以用一张 ...
- Mark IntelliJ IDEA 2018.2.3破解
来源:https://blog.csdn.net/qq_38060935/article/details/90377761
- vue Module parse failed: Unexpected token You may need an appropriate loader to handle this file type
1.错误截图: 2.错误原因:webpack 原生只支持 js 文件类型,及 es5 的语法 3.解决方法:在webpack.config.js中,增加以下配置 module: { rules: [ ...
- Unique -「企划」新生守则(?
随想随记,主要是整活. 红色贝雷帽大爷会在校园不定期游走,遇见记得打招呼. 面食堂冰沙类饮品请快速解决或者边喝边搅,如果发现饮品甜度骤减请快速前往最近的垃圾桶扔掉. 关于散养猫小黄和小黑. 如果看见小 ...
- Java开发学习(十四)----Spring整合Mybatis及Junit
一.Spring整合Mybatis思路分析 1.1 环境准备 步骤1:准备数据库表 Mybatis是来操作数据库表,所以先创建一个数据库及表 create database spring_db cha ...
- Azure Devops(十四) 使用Azure的私有Nuget仓库
哈喽大家好,最近因为工作的原因没有时间写文章,断更了俩月,今天我们开始继续研究Azure上的功能. 今天我们开始研究一下Azure的制品仓库,在之前的流水线的相关文章中,我们都使用到了制品仓库用来保存 ...