差分数组汇总

本文涉及知识点

算法与数据结构汇总

差分数组

令 ai = ∑ j : 0 i v D i f f i \sum_{j:0}^{i}vDiffi ∑j:0ivDiffi

如果 vDiffi1++,则ai1...全部++

如果vDiffi2--,则ai2...全部--。

令11 < i2 ,则:
{ a i 不变,不受加减影响 i < i 1 a i 不变,加减抵消 i > = i 2 a i + + o t h e r \begin{cases} ai不变,不受加减影响 && i < i1 \\ ai不变,加减抵消 && i >= i2\\ ai++ && other \\ \end{cases} ⎩ ⎨ ⎧ai不变,不受加减影响ai不变,加减抵消ai++i<i1i>=i2other

即:ai1...i2-1++ ,其它不变。

区间更新、单点更新时间复杂度:O(1)。

区间查询、单点查询:O(n)
依次查询 时间复杂度O(n),i从0到n-1查询ai的总时间复杂度是O(n)。

可与树状数组结合:更新查询全部是O(logn)

空间复杂度:O(n)

题解

难度分
【滑动窗口】【差分数组】C++算法:995K 连续位的最小翻转次数 1835
【区间合并 差分数组】2963:统计好分割方案的数目 1984
【差分数组】2772. 使数组中的所有元素都等于零 2029
二分查找 差分数组LeetCode2251:花期内花的数目 2022
【分解质因数 差分数组】2584. 分割数组使乘积互质 2159
【差分数组】1674. 使数组互补的最少操作次数 2333
【前缀和 二分查找 差分数组】2528最大化城市的最小供电站数目 2235
【差分数组】【图论】【分类讨论】【整除以2】3017按距离统计房屋对数目 2709
【上下界分析 差分数组】798得分最高的最小轮调

用map实现的差分

封装类

cpp 复制代码
template<class KEY=int,class VALUE=int>
class CMapDiff
{
public:
	void Set(KEY left, KEY rExclue, VALUE value) {
		m_mDiff[left]+= value;
		m_mDiff[rExclue]-= value;
	}
	vector<pair<KEY, VALUE>> Ans()const {
		vector<pair<KEY, VALUE>> res;
		VALUE sum = 0;
		for (const auto& [key,value]: m_mDiff) {			
			sum += value;
			res.emplace_back(make_pair(key, sum));
		}
		return res;
	}
protected:
	map<KEY, VALUE> m_mDiff;
};

【区间合并 差分 栈】3169. 无需开会的工作日

大约2024年7月3号发

mDiffsi++ mDiffei+1-- 表示si,ei 一场会议。
∀ \forall ∀mDiff的键 key,其下一个键为nkey。

则 ∀ \forall ∀k ∈ \in ∈ key,nkey) mDiff\[k都为0,省略。

即:
x = ∑ i : 0 k e y m D i f f i = ∑ i : 0 k m D i f f i x = \sum_{i:0}^{key}mDiffi \quad = \sum_{i:0}^{k}mDiffi x=∑i:0keymDiffi=∑i:0kmDiffi

如果x不为0,则[key,nkey)全部要开会。

二维差分

aij = ∑ i 1 : 0 i ∑ j 1 : 0 j v D i f f i j \sum_{i1:0}^i \sum_{j1:0}^jvDiffij ∑i1:0i∑j1:0jvDiffij

ai1...i2j1...j2 ++的操作:

vDiffi1j1++ vDiffi2+1j2+1++

vDiifi1j2+1-- vDiff2+1j1--
注意 :差分都是左闭右开空间

求前缀和的简单方法:

vColj = ∑ i 1 : 0 i v D i i f i 1 j \sum_{i1:0}^{i}vDiifi1j ∑i1:0ivDiifi1j

aij = ∑ j 1 : 0 j v C o l j 1 \sum_{j1:0}^j vColj1 ∑j1:0jvColj1

封装类

cpp 复制代码
template<class T = int >
class CDiff2
{
public:
	CDiff2(int r, int c):m_iR(r),m_iC(c) {
		m_vDiff.assign(m_iR, vector<T>(m_iC));
	}
	void Set(int r1, int c1, int r2Exinc, int c2Exinc,int iAdd) {
		m_vDiff[r1][c1] += iAdd;
		m_vDiff[r2Exinc][c2Exinc] += iAdd;
		m_vDiff[r1][c2Exinc] -= iAdd;
		m_vDiff[r2Exinc][c1] -= iAdd;
	}
	vector<vector<T>> Ans()const {
		vector<vector<T>> res(m_iR, vector<T>(m_iC));
		vector<T> vCols(m_iC);
		for (int r = 0; r < m_iR; r++) {
			T iSum = 0;
			for (int c = 0; c < m_iC; c++) {
				vCols[c] += m_vDiff[r][c];
				iSum += vCols[c];
				res[r][c] = iSum;
			}
		}
		return res;
	}
	
	const int m_iR, m_iC;
protected:
	vector<vector<T>> m_vDiff;
};

题解

难度分
【离散化 二维差分】850. 矩形面积 II 2335
【二维差分】2132. 用邮票贴满网格图 2364
【离散化 二维差分】391. 完美矩形

扩展阅读

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关推荐

我想对大家说的话
喜缺全书算法册》以原理、正确性证明、总结为主。
按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境: VS2022 C++17

如无特殊说明,本算法用**C++**实现。

相关推荐
不会C语言的男孩36 分钟前
C++ Primer Plus 第8章:函数探幽
开发语言·c++
William_wL_40 分钟前
【C++】模板进阶
c++
MC皮蛋侠客8 小时前
Google Test 单元测试指南
c++·单元测试·google test
艾莉丝努力练剑9 小时前
【Linux:文件】Ext系列文件系统进阶
linux·运维·服务器·c++·文件系统·文件io·ext
kkeeper~9 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
2401_868534789 小时前
论企业网络设计
数据结构
2401_8769641310 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
basketball61611 小时前
C++ NULL 和 nullptr 区别 以及 nullptr 的核心实现
java·开发语言·c++
Fre丸子_12 小时前
自定义文件夹选取功能
c++
思麟呀14 小时前
C++工业级日志项目(六)异步日志器
linux·c++·windows