【算法】前缀和

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 【算法】前缀和,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

目录

🍔前缀和:

         🍔模板

         🍔应用 


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

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!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131356.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!