归咎于寂寞的夏天.|

Phantasia1116

园龄:1年7个月粉丝:0关注:7

2024-03-06 22:55阅读: 12评论: 1推荐: 0

2.diff差分【模板】

  • [[#差分数组|差分数组]]
    • [[#差分数组#三个数组的关系|三个数组的关系]]
  • [[#题目描述|题目描述]]
  • [[#输入描述|输入描述]]
  • [[#输出描述|输出描述]]
  • [[#输入样例1|输入样例1]]
  • [[#输出样例1|输出样例1]]

差分数组

  • 如下叫做差分数组

\[d_{i} = a_{i} - a_{i-1} \]

  • 又有

\[\sum_{j=1}^{i} {d_{j}} = d_{1}+d_2+\dots+d_i \]

  • 而上述式子可以写作

\[d_{1}+d_2+\dots+d_{i}= (a_1-a_{0})+(a_2-a_1)+\dots+(a_{i-1}-a_{i-2})+(a_i-a_{i-1}) \]

  • 又因为 \(a_0=0\) 于是上式(左侧为一个前缀和数组)

\[\sum_{j=1}^{i} {d_{j}}=a_i \]

  • image.png|675
  • 差分数组可以实现后缀区间的修改,是静态的修改(修改完成之后进行询问,不可以边询问边修改)
  • 如果对 \(d_2\) 增加了 \(x\) ,那么 \(a_{2}、a_{3}、a_4\) 以后都会增加 \(x\) ,那么当在 \(d_4\) 处减少 x 后,就抵消了从 \(d_4\) 开始往后的修改,做到了只在 \(a_{2}、a_3\) 两个位置的修改(增加x)
  • image.png

三个数组的关系

  • image.png

  • 题目书写模板

  • 读入数组 => 求出差分数组 => 修改差分数组 => 更新原数组 => 求出前缀数组 => 打印结果

  • image.png

题目描述

给定一个长度为n的数组a,和两个整数p,q。

先进行p次区间加操作:将区间[l,r]的数字都加上�x。

再进行q次区间查询操作:求出[l,r]的数字之和。

对于每次区间查询操作,输出结果。

输入描述

第一行三个整数 n,p,q。(1≤n≤105,0≤p≤105,0≤10^5≤q)

第二行 n 个整数表示数组 a。(−109≤a_i​≤109)

接下来 p 行,每行三个整数 l,r,x。(1≤l≤r≤n,−109≤x≤109)

接下来q行,每行两个整数l,r。(1≤l≤r≤n)

输出描述

对于每次区间查询操作,输出结果。

输入样例1

5 1 2
1 1 1 2 2
1 4 2
1 3
1 5

输出样例1

9
15

Code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 9;
// 全局数组自动初始化为0
ll a[N], prefix[N], diff[N];
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, p, q;
cin >> n >> p >> q;
for (int i = 1; i <= n; ++i) cin >> a[i];
for (int i = 1; i <= n; ++i) diff[i] = a[i] - a[i - 1];
while (p--) {
int l, r;
ll x;
cin >> l >> r >> x;
diff[l] += x, diff[r + 1] -= x;
}
// 更新a
for (int i = 1; i <= n; ++i) a[i] = a[i - 1] + diff[i];
// prefix
for (int i = 1; i <= n; i++) prefix[i] = prefix[i - 1] + a[i];
while (q--) {
int l, r;
cin >> l >> r;
cout << prefix[r] - prefix[l - 1] << '\n';
}
return 0;
}

本文作者:Phantasia1116

本文链接:https://www.cnblogs.com/Phantasia/p/18057847

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

posted @   Phantasia1116  阅读(12)  评论(1编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起