当前位置: 首页 > article >正文

【算法】前缀和

目录

🍔前缀和:

         🍔模板

         🍔应用 


🎆音乐分享(点击链接可以听哦)

A Hundred Miles(一百英里) - Meat Puppets - 单曲 - 网易云音乐 (163.com)


  

 

前缀和:

什么是前缀和:
原数组: a[1], a[2], a[3], a[4], a[5], …, a[n]
前缀和 Si为数组的前 i项和
前缀和: S[i] = a[1] + a[2] + a[3] + … + a[i]

求 [l, r]中的和, 即为 S[r] - S[l-1]

前缀和的作用:
快速求出元素组中某段区间的和

方法:

首先做一个预处理,定义一个sum[]数组,sum[i]代表a数组中前i个数的和

for(int i = 1; i <= n;i++)

    sum[i] = sum[i - 1] + a[i];   
}

这样,对于每个询问,只需要执行 sum[r]-sum[l-1]。输出原序列中从第l个数到第r个数的和的时间复杂度变成了O(1)。

注意:

下标最好从1开始(从0开始也可以,主要是根据个人习惯)

🚥🚥🚥🚥🚥🚥

模板

795. 前缀和 - AcWing题库 

输入一个长度为 n 的整数序列。

接下来再输入 m 个询问,每个询问输入一对 l,r。

对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。

输入格式

第一行包含两个整数 n 和 m。

第二行包含 n 个整数,表示整数数列。

接下来 m 行,每行包含两个整数 l 和 r,表示一个询问的区间范围。

输出格式

共 m 行,每行输出一个询问的结果。

 

 

代码

#include <iostream>

using namespace std;

const int N = 100010;

int n, m;
int a[N], s[N];

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);

    for (int i = 1; i <= n; i ++ ) s[i] = s[i - 1] + a[i]; // 前缀和的初始化

    while (m -- )
    {
        int l, r;
        scanf("%d%d", &l, &r);
        printf("%d\n", s[r] - s[l - 1]); // 区间和的计算
    }

    return 0;
}

⭐⭐⭐⭐⭐⭐ 

应用 

Problem - D - Codeforces

嘿嘿嘿,CF虐我千百遍,我待CF如初见! (doge) 

🏳️‍🌈🏳️‍🌈🏳️‍🌈

小吉是真的没有想到这道题可以用前缀和来写(学了前缀和,但是没有发挥用途,我真的会乌鱼呀,让我怎么荔枝呀(纯纯坤语言doge)) 

 🏳️‍🌈🏳️‍🌈🏳️‍🌈

这道题依然传承了cf的基本格式( t 个样例,然后进行讨论)

cf的题,都会给出样例,如果题目描述中有样例解释,一定要看,因为有时候题目看不懂(呜呜呜,因为是英语),但是看样例却可以看懂,甚至可以做对题

题目含义:

总个数 n  

题目中给出了 l r k 三个字母,其中,l 可以代表左边界的下标,r 可以代表右边界的下标,

(l - r + 1)代表需要替换的长度,这个长度中的每个数的大小是 k 

(比如 l=2 r=3 k=3,那么长度为2,为 [ 3 , 3] )

情况1:替换的长度(l - k + 1) = n

那么所有的数(n个数)的值都为k

情况2:替换的长度(l - k + 1) < n

由于替换的长度(l - k + 1) < n,那么就要用原数组的数来补全没有被替换掉的数

这个时候,我们应该如何在原数组里面对应被替换掉的数的位置和数组中剩下的数的位置和大小呢,这就要用到前缀和了 

代码 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll a[N],sum[N];
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,q;
		cin>>n>>q;
		for(int i=1;i<=n;i++)cin>>a[i];
		for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];//前缀和
		while(q--){
			int l,r,k;
			cin>>l>>r>>k;
			ll ans=sum[n]-(sum[r]-sum[l-1])+(r-l+1)*k;
			if(ans%2==0)cout<<"NO"<<endl;
			else cout<<"YES"<<endl;
		}
	}
}

Code over!


http://www.kler.cn/a/2934.html

相关文章:

  • 谷歌Gemini与Anthropic Claude对比测试引发争议:AI竞赛暗流涌动
  • 4-pandas常用操作
  • 细说STM32F407单片机轮询方式读写SPI FLASH W25Q16BV
  • 活着就好20241226
  • Mybatis 小结
  • CentOS Stream 9 挂载Windows共享FTP文件夹
  • 解决win10任何程序打开链接仍然为老旧IE的顽固问题[修改默认浏览器]
  • 重构类关系-Pull Up Constructor Body构造函数本体上移三
  • 2023年通过CDGA的朋友可以考CDGP数据治理专家认证啦!
  • 传感器之相机介绍和使用
  • 游戏开发中常用的算法(持续更新)
  • 206. 反转链表
  • [数据结构]排序算法
  • Swift入门
  • 类和对象 - 下
  • 第二十一天 数据库开发-MySQL
  • 大文件上传
  • forward函数——浅学深度学习框架中的forward
  • CVPR 2023 | 旷视研究院入选论文亮点解读
  • HCIP-6.2NAT协议原理与配置
  • Qt5.12实战之控件设计
  • 并查集、并查集+离线、并查集+倒叙回答
  • JVM知识整理
  • Python实现人脸识别检测, 对美女主播照片进行评分排名
  • 串口通信(STM32演示实现)
  • C++ 八股文(简单面试题)