🎆音乐分享
光辉岁月 (粤语版)_BEYOND
所谓差分,就是前缀和的逆运算
(不懂前缀和的同学可以去C站看一下😂)
797. 差分 - AcWing题库
代码
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N], b[N];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
b[i] = a[i] - a[i - 1]; //构建差分数组
}
int l, r, c;
while (m--)
{
scanf("%d%d%d", &l, &r, &c);
b[l] += c; //将序列中[l, r]之间的每个数都加上c
b[r + 1] -= c; //因为是差分,所以只需要看一下序列的开头和结尾即可
} //开头加一,那么从开头到后面的序列都加一
for (int i = 1; i <= n; i++)
{
a[i] = b[i] + a[i - 1]; //前缀和运算
printf("%d ", a[i]);
}
return 0;
}
差分的应用
100. 增减序列 - AcWing题库
代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
typedef long long LL;
int n;
int a[N], b[N];
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
for (int i = 1; i <= n; i ++ ) b[i] = a[i] - a[i - 1];//差分数组
LL p = 0, q = 0;
for (int i = 2; i <= n; i ++ )
if (b[i] > 0) p += b[i];//正数加上去
else q -= b[i]; //负数先变成正数,再加上去
cout << max(p, q) << endl;//因为得保证所有项大小一样,所以是max而不是min
cout << abs(p - q) + 1 << endl;
return 0;
}
😎使用差分的好处&&为什么要用到abs
对原序列的操作可以变成仅仅对序列 前后两个数 的操作
😎p+=b[i]:因为上面图片中已经了解了b[i]的含义,实际上p+=b[i]就是求出能把b[i]变成0所需要的次数
q-=b[i]同理
😎为什么for循环里面,i是从2开始的,而不是1
我们可以看一下上面的图片的分析过程
b[1]是一个已经确定的数
😎为什么到最后要+1
因为以b[1]为基准(上面图片的分析里面有讲b的含义)
b[i]的值一共有0~|p-q|,一共|p-q|+1种
Code over!