首页 > 其他分享 >前缀和与差分

前缀和与差分

时间:2024-12-24 15:30:13浏览次数:7  
标签:pre 前缀 int 差分 数组 diff

前缀和与差分

1. 一维前缀和

在学习前缀和之前,我们先来看一个题目,了解前缀和的用处。

链接: 题目链接

题目描述

给定一个数组a,有q次询问,对于每次询问:给定两个数 l,r。求第l个数到第r个数的和。

输入描述

第一行一个整数表示样例个数T,1<=T<=10 。
对于每组样例:
第一行两个整数n,q, 分别表示数组长度和询问次数。1<=n,q<=1e5.
第二行n个整数,表示数组a,-1e9<=ai<=1e9.
接下来q行,每行两个整数l,r 表示询问的区间。

输出描述

对于每组样例,一行一个整数表示答案。

输入样例

2
5 3
1 2 3 4 5
1 2
2 5
3 4
7 2
-1 9 -10 8 2 6 11
1 5
2 7

输出样例

3
14
7
8
26

暴力解法:
对于每一次询问,遍历区间进行求和,时间复杂度为O(T* n*q),最大为1e11,所以暴力必然超时。

改变思路,用前缀和,对于每一次询问都可以通过O(1)的复杂度实现。

实现方法:再开一个数组pre,用来保存a数组的前 i 项和。
即:pre[i]=pre[i-1]+a[i];
要求 l - r 区间的和即求 : pre[r]-pre[l-1];

话不多说,上代码

一维前缀和

//2024 jin
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 9;
ll a[N], pre[N];//记得开ll ,int会爆
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin >> t;
	while (t--)
	{
		int n, q;
		cin >> n >> q;
		for (int i = 1; i <= n; i++)
		{
			cin >> a[i];
			//前缀和
			pre[i] = pre[i - 1] + a[i];
		}
		while (q--)
		{
			int l, r;
			cin >> l >> r;
			cout << pre[r] - pre[l - 1] << '\n';
		}
	}
	return 0;
}

2.一维差分

首先来介绍一下差分数组(diff),diff[i]=a[i]-a[i-1],差分与前缀和的区别就是一个是减,一个是加。

由上面一维前缀和我们了解到前缀和可以快速求出一个区间的和。接下来我们看看差分有哪些妙用。

1.还原成a[i]:对差分数组进行前缀和能还原出a[i]。
2.区间修改:差分数组能够快速的对区间进行修改,时间复杂度为O(1)。

接下来看一个题目
链接: 题目链接

题目描述

给定一个长度为n的数组a,和两个整数p,q。
先进行p次区间加操作:将区间[l,r]的数字都加上x。
再进行q次区间查询操作:求出[l,r]的数字之和。
对于每次区间查询操作,输出结果。

输入描述

第一行三个整数

标签:pre,前缀,int,差分,数组,diff
From: https://www.cnblogs.com/jin1/p/18627802

相关文章

  • USACO24DEC Cake Game S 题解 [ 黄 ] [ 前缀和 ] [ adhoc ]
    CakeGame:小清新前缀和题,但是我场上想了半天优先队列贪心假完了/ll/ll/ll。观察本题有三个重要的结论,我们依次进行观察。不难发现,第二个牛一定会拿\(\frac{n}{2}-1\)个蛋糕走。同时它拿走的蛋糕一定是左边一段、右边一段。如果它要使自己的分数最大化,那么显然就是要将左边和......
  • 差分约束系统
    差分约束用于求有\(n\)个变量,\(m\)条限制,每条限制只与两个变量的差有关的问题的一组解。一般可以转化为最短路或者最长路解决。最短路:用三角形不等式\(dis_v\ledis_u+w\)来保证解合法,这样一条不等式等价于\(x_v\lex_u+w\)。最长路:类似最短路,用\(dis_v\gedis_u+w\)来保证解......
  • 【差分约束】学习笔记
    BasicTips差分约束,即为存在一个差分约束系统,即类似\(x_i-x_j\leqk\)的\(n\)元一次不等式组,求出一组解使得该组内所有不等式全部成立,即\(x_1=s_1,x_2=s_2\dotsx_n=s_n\),否则判无解。对于满足条件的一个解集\(\{s_1,s_2,s_3,\dots,s_n\}\),集合\(\{s_1+t,s_2......
  • 【学习笔记】高位前缀和(SOSDP)
    高位前缀和解决这样的问题:给定\(f_i\),其中\(i\in[0,2^n-1]\),求解\(\sum\limits_{j\ini}f_j\)。考虑一维前缀和:for(inti=1;i<=n;i++){ sum[i]=sum[i-1]+a[i];}二位前缀和:for(inti=1;i<=n;i++){ for(intj=1;j<=n;j++){ sum[i][j]=sum[i][j-1]+a[i][j]; }}for......
  • LeetCode100之实现Trie前缀树(208)--Java
    1.问题描述Trie(发音类似"try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补全和拼写检查。请你实现Trie类:Trie() 初始化前缀树对象。voidinsert(Stringword) 向前缀树中插入字符串 word ......
  • 铺地毯(二维差分/枚举区间)
    题目:链接:https://ac.nowcoder.com/acm/problem/16593https://www.luogu.com.cn/problem/P1003思路:二维差分:差分矩阵初始值全为0,在[i,j]~[a,b]区间+v,就在mat[i,j]+v,mat[a+1,j]-v,mat[i,b+1]-v,mat[a+1,b+1]+v然后进行二维前缀和:sum[i,j]=左+上-左上+自己;枚举区间:开一个......
  • 二维差分
    [Algo]二维前缀和&二维差分1.最大的以1为边界的正方形//1.最大的以1为边界的正方形//https://leetcode.cn/problems/largest-1-bordered-square/description/intget(vector<vector<int>>&v,inti,intj){return(i<0||j<0)?0:v[i][j];}voidbuild(......
  • 【优选算法】Prefix-Kage:前缀和的算法影(下)
    文章目录1.前缀和+后缀和1.1寻找数组的中心下标1.2除自身以外数组的乘积2.前缀和+哈希表2.1和为k的子数组2.2和可被k整除的子数组2.3连续数组3.二维前缀和拓展3.1矩阵区域和希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力!本篇是前缀和算法......
  • 校门外的树(一维差分)
    题目:链接:https://ac.nowcoder.com/acm/problem/16649题意:给出m片区域,将这m片区域的树砍掉,问0~l上还有多少棵树思路:差分一维差分:构造一个初始元素都为0的dif数组,长度为[0,n]如果在i~j上+k,那么令dif[i]+k,dif[j+1]-k进行若干次操作后,进行前缀和.(再加到原数组上,得到结果)......
  • 前缀和
    [Algo]前缀和1.求arr所有子数组中累加和为aim的最长子数组长度//1.求arr所有子数组中累加和为aim的最长子数组长度//https://www.nowcoder.com/practice/36fb0fd3c656480c92b569258a1223d5intf1(vector<int>&v,intaim){unordered_map<int,int>m;//key:前......