前缀和与差分

前缀和与差分

前缀和

定义:前缀和可以简单理解为「数列的前 n 项的和」,是一种重要的预处理方式,能大大降低查询的时间复杂度。

一维前缀和

原理

数组sum用于储存前 i 个元素的和, 数组a为原数组
sum[0] = a[0] = 0
sum[1] = a[1]
sum[2] = sum[1] + a[2] = a[1] + a[2]
sum[3] = sum[2] + a[3] = a[1] + a[2] + a[3]
sum[n] = sum[n - 1] + a[n] = a[1] + ..... + a[n]
由此我们可以得出:sum[i] = sum[i - 1] + a[i] 这一递推公式

模板

for (int i = 1; i <= n; i++)
sum[i] = sum[i - 1] + a[i];

时间复杂度:O(n)

模板题:一维前缀和
参考代码:代码

二维前缀和

原理

如图所示,黑色边框为a[1][1]到a[i][j]之间所有元素的和(sum[i][j]),蓝色边框为a[1][1]到a[i - 1][j]之间所有元素的和(sum[i - 1][j]),橙色边框为a[1][1]到a[i][j - 1]之间所有元素的和(sum[i][j - 1])。
观察图的面积关系,我们可以得到这一递推关系:

sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i]

这一递推关系即为二维前缀和的递推公式。

模板

for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j];

时间复杂度:O(n * m)

模板题:二维前缀和

参考代码:代码

与前缀和有关的题目

简单的D题

参考代码:代码

差分

类似于数学中的求导和积分,差分可以看成前缀和的逆运算。

一维差分

原理

一维差分数组其实就是原数组中该位置的元素减去上一位置的元素
如代码所示:
数组s为差分数组,数组a为原数组。

void insert(int l, int r, int y)
{
s[l] = s[l] + y;
s[r + 1] = s[r + 1] - y;
}
for (int i = 1;i <= n;i++)
insert(i, i, a[i]);

在对数组a的遍历之时,差分数组s在 i 的位置加上原数组a在 i 位置的值,在 i + 1 位置减去原数组a在 i 位置的值,同理在 i - 1 位置时,s在 i - 1 的位置也减去了原数组在 i - 1 位置的值, 因此 s[i] = a[i] - a[i - 1]。

模板

void insert(int l, int r, int y)
{
s[l] = s[l] + y;
s[r + 1] = s[r + 1] - y;
}

时间复杂度:O(n)

模板题:一维差分

参考代码:代码

二维差分

原理

二维差分可以类似于一维差分进行理解

void insert(int x1, int y1, int x2, int y2, int y)
{
s[x1][y1] = s[x1][y1] + y;
s[x2 + 1][y1] = s[x2 + 1][y1] - y;
s[x1][y2 + 1] = s[x1][y2 + 1] - y;
s[x2 + 1][y2 + 1] = s[x2 + 1][y2 + 1] + y;
}
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
insert(i, j, i, j, q[i][j]);

s[x1][ y1 ] +=c ; 让整个s数组中蓝色矩形面积的元素都加上了c。

s[x1,][y2+1]-=c ; 让整个s数组中绿色矩形面积的元素再减去c,使其内元素不发生改变。

s[x2+1][y1]- =c ; 让整个s数组中紫色矩形面积的元素再减去c,使其内元素不发生改变。

s[x2+1][y2+1]+=c; 让整个s数组中红色矩形面积的元素再加上c,红色内的相当于被减了两次,再加上一次c,才能使其恢复。

模板

void insert(int x1, int y1, int x2, int y2, int y)
{
s[x1][y1] = s[x1][y1] + y;
s[x2 + 1][y1] = s[x2 + 1][y1] - y;
s[x1][y2 + 1] = s[x1][y2 + 1] - y;
s[x2 + 1][y2 + 1] = s[x2 + 1][y2 + 1] + y;
}

时间复杂度:O(n * m)

模板题:二维差分

参考代码:代码

与差分有关的题目

最高的牛

参考代码:代码

本文作者:APF

本文链接:https://www.cnblogs.com/APFLY/p/18327456

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   APF  阅读(118)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 【.NET】调用本地 Deepseek 模型
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.

作曲 : Reol

作词 : Reol

fade away...do over again...

fade away...do over again...

歌い始めの一文字目 いつも迷ってる

歌い始めの一文字目 いつも迷ってる

どうせとりとめのないことだけど

伝わらなきゃもっと意味がない

どうしたってこんなに複雑なのに

どうしたってこんなに複雑なのに

噛み砕いてやらなきゃ伝わらない

ほら結局歌詞なんかどうだっていい

僕の音楽なんかこの世になくたっていいんだよ

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.

目の前 広がる現実世界がまた歪んだ

目の前 広がる現実世界がまた歪んだ

何度リセットしても

僕は僕以外の誰かには生まれ変われない

「そんなの知ってるよ」

気になるあの子の噂話も

シニカル標的は次の速報

麻痺しちゃってるこっからエスケープ

麻痺しちゃってるこっからエスケープ

遠く遠くまで行けるよ

安定なんてない 不安定な世界

安定なんてない 不安定な世界

安定なんてない きっと明日には忘れるよ

fade away...do over again...

fade away...do over again...

そうだ世界はどこかがいつも嘘くさい

そうだ世界はどこかがいつも嘘くさい

綺麗事だけじゃ大事な人たちすら守れない

くだらない 僕らみんなどこか狂ってるみたい

本当のことなんか全部神様も知らない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.