首页 > 其他分享 >前缀和

前缀和

时间:2023-07-23 09:55:15浏览次数:32  
标签:std 前缀 int sum long include

在学完数组后常会遇见这样的题如B3612【深进1.例1】求区间和

有n个数,$ a1,a2,a3.....an(ai<=105),m<=103$ ,$l$,$r$,求区间内的和;

$n$个数:$2$ $7$ $9$ $1$ $3$ $6$ $5$ $3$

你会写出这样的代码:

while(m--){
	for(int i=起点;i<=终点;i++)
		sum+=a[i];
	...............

抛开题目,我们来说一下前缀和优化

有$8$个数:$a[1]$~$a[9]$:

$a$ :$1$ $2$ $3$ $4$ $5$ $6$ $7$ $8$

创建一个$sum$数组,使得$sum[i]=$从第$1$项到第$i$项之和

$ sum[i]=a[1]+a[2]...+a[i] $

$ a[1]+a[2]..+a[i-1]=sum[i-1] $

  • 得到一个前缀和公式:$ sum[i]=sum[i-1]+a[i] $

得到Code:

#include<iostream>
using namespace std;
int a[9]={0,1,2,3,4,5,6,7,8};
int sum[9];
int main(){
	sum[1]=a[1];
	for(int i=2;i<=8;i++)
		sum[i]=sum[i-1]+a[i];
	for(int i=1;i<=8;i++)
		cout<<sum[i]<<" ";
	return 0;
}

标准前缀和:

#include<iostream>
using namespace std;
long long a[100005],n;
long long sum[100005];
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum[i]=a[i]+sum[i-1];
	}
	for(int i=1;i<=n;i++) cout<<sum[i]<<" ";
	return 0;
}

回到题目

通过前缀和公式,最早的题目B3612【深进1.例1】求区间和代码如下:

#include<iostream>
using namespace std;
long long a[100005],n,m;
long long sum[100005];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum[i]=a[i]+sum[i-1];
	}
	for(int i=1;i<=m;i++){
		int l,r;
		cin>>l>>r;
		cout<<sum[r]-sum[l-1];
	}
	return 0;
}

例题P5745 【深基附B例】区间最大和

方法:前缀和 $+$ 二分

Code:

#include<iostream>
#include<cmath>
using namespace std;
long long a[4000005],n,m;
long long sum[4000005],maxn,mi,mj;
int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum[i]=a[i]+sum[i-1];
	}
	for(int i=1;i<=n;i++){
		int l=i,r=n,mid;
		while(l<=r){
        	mid=(r+l)/2;
        	if(sum[mid]-sum[i-1]>m) r=mid-1;
      		else l=mid+1;
    	}
    	if(sum[r]-sum[i-1]<=m){
    		if(sum[r]-sum[i-1]>maxn){
    			mi=i;
      			mj=r;
      			maxn=sum[r]-sum[i-1];
			}
		}
	}
	cout<<mi<<" "<<mj<<" "<<maxn;
	return 0;
}

标签:std,前缀,int,sum,long,include
From: https://www.cnblogs.com/2509-SYM/p/17574707.html

相关文章

  • 全局路由前缀配置
    1、新建RouteConventio.cs文件///<summary>///全局路由前缀配置///</summary>publicclassRouteConventio:IApplicationModelConvention{///<summary>///定义一个路由前缀变量///</summary>privatere......
  • 2-3 编写函数 htoi(s),把由十六进制数字组成的字符串(包含可选的前缀 0x 或 0X)转换为与
    ArchlinuxGCC13.1.1 202304292023-07-2219:48:23星期六 点击查看代码#include<stdio.h>#include<ctype.h>inthtoi(constchar*s);intmain(){chararr[4]="0x3A";intresult=htoi(arr);printf("%d\n",resu......
  • jsp 超链接带系统前缀
    如: <a href="www.iteye.com">iteye</a> 网页生成后点击此超链接,始终有如http://localhost:8080的前缀,变成http://localhost:8080/www.iteye.com  解决:加上http://前缀   <a href="http://www.iteye.com">iteye</a> ......
  • PKUSC2018 最大前缀和
    这个期望显然是诈骗,即统计每种排列最大前缀和之和。对于某个排列\(a\),令\(s(l,r)=\sum\limits_{k=l}^ra_k\)。考虑前缀\([1,i]\)成为答案的充要条件:\(\forall1<j\lei,s(j,i)\ge0\),否则可以去掉这段。\(\forallj>i,s(i+1,j)<0\),否则加上这段不劣(钦定取的是最大并且最靠......
  • java base64 去掉前缀
    JavaBase64去掉前缀的实现步骤在Java中,要去掉Base64编码的前缀,可以通过一系列的步骤来实现。下面是整个流程的步骤表格:步骤描述步骤1将Base64编码的字符串转换为字节数组步骤2使用Java提供的Base64解码类解码字节数组步骤3将解码后的字节数组转换为字符串......
  • abc089 <前缀和>
    题目D-PracticalSkillTest思路计算出所有结点在跳转过程中的前缀和,从而O1查询根据数据范围,实际上不需要二分,直接开相同大小的数组即可(代码中使用二分)代码Code//https://atcoder.jp/contests/abc089/tasks/abc089_d#include<iostream>#include<algorith......
  • 「前缀和」k倍区间
    本题蓝桥OJ第97题的题解(蓝桥OJ上的相同题解也是我发的)题面题目描述给定一个长度为N的数列,\(A_1,A_2,\dots,A_N\),如果其中一段连续的子序列\(A_i,A_{i+1},\dots,A_j(i\leqj)\)之和是K的倍数,我们就称这个区间\([i,j]\)是K倍区间。你能求出数列中总共有多少个K倍区间......
  • abc086d <二维前缀和 同余>
    题目D-Checker思路坐标对2k取余,通过二维前缀和计算满足条件的个数;也可对k取余,参考;代码Code//https://atcoder.jp/contests/abc086/tasks/arc089_b//二维前缀和同余#include<iostream>#include<algorithm>#include<vector>#include<cstring>usi......
  • abc084d <素数筛 前缀和>
    题目D-2017-likeNumber思路筛出数据范围1e5范围内的素数检查每个素数是否为2017-like对1~1e5内的2017-like求前缀和,回答询问总结如果数据范围允许,进行预处理,查表回答询问代码Code//https://atcoder.jp/contests/abc084/tasks/abc084_d#include<iostre......
  • 算法——前缀和 + 两数相加、相减
    求数组中,连续区间的大小,可使用前缀和相减得到。进阶变形若想得到区间大小等于target,暴力枚举前缀和相减。复杂度O(n^2)优化算法:将每次求得的前缀和放入hashMap中,S[j]-S[i]==target,(j>i)求出S[j]后,判断hashMap中是否存在S[i]=S[j]-target值,复杂度O(n)参考链接使数......