第4次课 前缀和与差分 A

课堂学习

前缀和数组

前1个收购点:3箱
前2个收购点:3+2=5箱
前3个收购点:3+2+5=10箱
以此类推…

数组a存储10个收购点的箱数。
收购点编号从1~10,数组下标也从1开始使用。
下标0位置直接赋值0

#include<bits/stdc++.h>
using namespace std;
int main(){//创建并初始化数组a:从下标1开始用,下标0赋值0int a[11]={0,3,2,5,6,6,1,4,1,7,3};//创建并初始化数组sint s[11]={};//1.初始条件:s[1]=a[1]s[1]=a[1];//2.根据递推关系推导前缀和:s[i]=s[i-1]+a[i]  (i>=2)for(int i=2;i<=10;i++){s[i]=s[i-1]+a[i];}//3.循环输出前缀和for(int i=1;i<=10;i++){cout<<s[i]<<" ";}return 0;
}

课堂训练

2915 计算区间和

描述

输入 n 个整数,再输入m个区间,每个区间的起点下标L,终点下标R。
对于每个区间,输出n个整数中从下标L到下标R的区间和。

输入描述

第一行包括两个整数n和m。(1≤n,m≤500000)
第二行包括n个整数。(1≤整数≤100)
接下来有m行,每行包含两个整数L和R,表示区间范围。(0<L≤R≤n)

输出描述

输出有m行,每行一个整数,表示一个区间和。

样例输入 1 

10 3
2 1 3 6 4 20 15 10 4 11
3 7
1 9
5 8

样例输出 1 

48
65
49

简单分析

//2915 计算区间和
#include<bits/stdc++.h>//万能头文件
using namespace std;
const int N=500010;
int a[N],s[N];//a是原数组,s是前缀和数组
int main(){//输入数据int n,m;cin>>n>>m;for(int i=1;i<=n;i++){cin>>a[i];}s[1]=a[1];//求出任意位置的前缀和for(int i=2;i<=n;i++){s[i]=s[i-1]+a[i];}int L,R;for(int i=1;i<=m;i++){cin>>L>>R;cout<<s[R]-s[L-1]<<endl;}return 0;
}

练一练: 

总结:前缀和

③前缀和优势:可以1步减法算出区间和。
下标[L~R]的区间和=s[R]-s[L-1]
④前缀和使用场景:多次计算区间和。
注意:区间起点L一般从1开始。
如果L=0,就会导致s[L-1]为s[-1]的情况。
 

2916 K个元素和

描述

输入n个整数,求出所有连续且长度为K的元素总和。

输入描述

第一行包括两个整数n和K。(1≤K≤n≤500000)
第二行包括n个整数。(1≤整数≤100)

输出描述

输出一行,包含若干数字,每个数字表示1个元素总和。

样例输入 1 

10 3
2 1 3 6 4 5 8 7 0 9

样例输出 1 

6 10 13 15 17 20 15 16

提示

根据样例得知,在10个数字中求连续且长度为3的元素总和,依次得到:
2+1+3=6;1+3+6=10;3+6+4=13;6+4+5=15;
4+5+8=17; 5+8+7=20; 8+7+0=15; 7+0+9=16。

#include<bits/stdc++.h>
using namespace std;
int a[500010]={};//原数组
int s[500010]={};//前缀和数组
int main(){int n,K;cin>>n>>K;//1.输入n个元素; 注意从下标1开始使用for(int i=1;i<=n;i++){cin>>a[i];}//2.循环推导前缀和s[1]=a[1];for(int i=2;i<=n;i++){s[i]=s[i-1]+a[i];}//3.遍历所有长度K的区间;计算输出区间和for(int i=K;i<=n;i++){cout<<s[i]-s[i-K]<<" ";}return 0;
}

4434 m倍的区间

描述

输入 n 个整数,在所有连续且长度为 K 的区间中,统计有多少区间和是 m 的倍数。

输入描述

第一行包括三个整数 n,K 和 m。
第二行包括 n 个整数。

输出描述

输出一个整数,表示有多少个区间和是 m 的倍数。

样例输入 1 

5 3 2
2 1 3 6 4

样例输出 1 

2

提示

数据范围与提示

1≤m≤K≤n≤500000,1≤整数≤100
长度为3的区间有:2 1 3,1 3 6,3 6 4。
区间2 1 3和1 3 6的和是2的倍数。

#include<bits/stdc++.h>
using namespace std;
int a[500010]={};//原数组
int s[500010]={};//前缀和数组
int main(){int n,k,m;cin>>n>>k>>m;for(int i=1;i<=n;i++){cin>>a[i];}//推导前缀和数组s[1]=a[1];for(int i=2;i<=n;i++){s[i]=s[i-1]+a[i];}int ans=0;//遍历所有长度K的区间for(int i=k;i<=n;i++){int t=s[i]-s[i-k]; //计算区间和if(t%m==0){ //判断区间和是m倍数ans++;}}cout<<ans;return 0;
}

4433 最大区间和

描述

输入 n 个整数,在所有连续且长度为K的区间中,找到最大的区间和。

输入描述

第一行包括两个整数 n 和 K。
第二行包括 n 个整数。

输出描述

输出两行。第一行一个整数,表示最大区间和。
第二行两个整数,表示最大区间和的起点下标和终点下标。

样例输入 1 

10 3
2 1 3 6 4 5 8 7 5 3

样例输出 1 

20
6 8

提示

数据范围与提示

1≤K≤n≤500000,1≤整数≤100
样例中最大区间下标范围:6~8,区间和为20。
注意:如果多个区间和同为最大,取第1个区间。

#include<bits/stdc++.h>
using namespace std;
int a[500010]={};//原数组
int s[500010]={};//前缀和数组
int main(){int n,K;cin>>n>>K;//1.输入n个元素; 注意从下标1开始使用for(int i=1;i<=n;i++){cin>>a[i];}//2.循环推导前缀和s[1]=a[1];for(int i=2;i<=n;i++){s[i]=s[i-1]+a[i];}//3.遍历所有长度K的区间//先计算区间和,再取最大的区间和int res=0;//最大区间和int b,e;//起点下标b,终点下标efor(int i=K;i<=n;i++){//终点下标:i//起点的前1个下标:i-Kint t=s[i]-s[i-K];if(t>res){res=t;b=i-K+1;e=i;}}//4.输出结果cout<<res<<endl;cout<<b<<" "<<e<<endl;return 0;
}

差分

练一练 

差分性质

差分理论 

4436 混合操作

描述

输入 n 个整数,计算区间和。

输入描述

第一行包括一个整数 n。
第二行包括 n 个整数。
第三行包括一个整数 m,表示需进行 m 次操作。
操作包括两种:1 表示计算区间和;2 表示修改 n 个整数的其中 1 个。(操作 2 只有 1 次)
接着有 m 行,每行表示 1 次操作:
如果第一个数字为 1,后面跟着区间的起点 L,终点 R;
如果第一个整数为 2,后面跟着被修改整数所在位置 k,修改为整数 num。

输出描述

输出 m−1 行,每行一个整数,表示一个区间和。

样例输入 1 

10
2 1 3 6 4 20 15 10 4 11
5
1 3 7
1 4 9
2 8 20
1 7 10
1 5 8

样例输出 1 

48
59
50
59

提示

数据范围与提示

1≤n≤100000,1≤整数≤100,1≤m≤100000
对 10 个整数做 5 次操作:
第1次:计算[3~7]区间和,结果48;
第2次:计算[4~9]区间和,结果59;
第3次:修改第8个数字10,修改为20;
第4次:计算[7~10]区间和,结果50;
第5次:计算[5~8]区间和,结果59。

#include<bits/stdc++.h>
using namespace std;
int a[100010]={}; //原数组
int s[100010]={}; //前缀和数组
int main(){int n,m;cin>>n;//1、输入n个整数for(int i=1;i<=n;i++)	cin>>a[i];//2、推导前缀和s[1]=a[1];for(int i=2;i<=n;i++)	s[i]=s[i-1]+a[i];//3、遍历m次操作,判断并处理cin>>m;int c;//操作标记int L,R;int k,num;for(int i=1;i<=m;i++){ //m次操作cin>>c;if(c==1){ //计算区间和cin>>L>>R;cout<<s[R]-s[L-1]<<endl;}else{ //修改一个整数cin>>k>>num;a[k]=num; //元素a[k]赋值num//重新计算前缀和s[1]=a[1];for(int j=2;j<=n;j++)	s[j]=s[j-1]+a[j];}}return 0;
}

 课后作业

2919 最要强的飞行员

描述

在一次电子模拟作战中,假设敌方设置了一条防线,防线上依次有n个据点。每个据点都有一个牢固值,数值越大表示越牢固。
司令部计划对n个据点进行m轮攻击,每轮攻击一段连续范围的据点,每段范围上的据点都存在一个总牢固值。
有一位最要强的飞行员,申请在总牢固值最大的一轮出战。
请你编写程序找到最大的总牢固值。

输入描述

第一行包括两个整数n和m。(1≤n,m≤500000)
第二行包括n个整数,依次表示n个据点的牢固值。(1≤整数≤100)
接下来m行,每行两个正整数L和R,表示一轮范围。(1≤L≤R≤n)

输出描述

输出一个整数,表示最大的总牢固值。

样例输入 1 

7 2
2 10 5 3 6 4 9
3 5
6 7

样例输出 1 

14

提示

输入样例中m=2,表示有2轮攻击。
第1轮攻击从3~5,总牢固值5+3+6=14。
第2轮攻击从6~7,总牢固值4+9=13。
两轮攻击总牢固值最大14。

#include<bits/stdc++.h>
using namespace std;
int a[500001],s[500001];
int main(){int n,m;int L,R,res=0;//res存储最大总牢固值cin>>n>>m;for(int i=1;i<=n;i++){cin>>a[i];//输入据点牢固值s[i]=s[i-1]+a[i];//计算该据点前缀和}for(int i=1;i<=m;i++){cin>>L>>R;//输入一轮打击范围if((s[R]-s[L-1])>res){ //判断当前据点总牢固值是否大于resres=s[R]-s[L-1];}}cout<<res;//输出最大总牢固值resreturn 0;
}

2939 纸牌PK

描述

小童和小程每次遇到谁优先的问题,都会采用抽一张纸牌比大小的方式决定,总采用这种方式,难免感到无趣。
小童今天突发奇想,修改了抽纸牌的方式。修改后的方式是这样的:两人轮流在n张纸牌中抽取m轮,每轮抽取连续一定范围的纸牌,计算m轮抽取中所有牌面上的数字总和,最终谁的数字总和大,谁获得优先权。

输入描述

第一行包括两个整数n和m。(1≤m,n≤500000)(1≤m≤100)
第二行包括n个整数,依次表示n张纸牌上的数字。(1≤整数≤100)
接下来m行,每行两个正整数L和R,表示小童每轮抽牌的范围。
接下来m行,每行两个正整数L和R,表示小程每轮抽牌的范围。(1≤L≤R≤n)

输出描述

输出一个字符,小童数字总和大,输出T;小程数字总和大,输出C;总和相等输出D。

样例输入 1 

7 3
2 10 5 3 6 4 9
3 5
6 7
2 7
2 6
1 2
1 6

样例输出 1 

C

提示

输入样例中m=3,表示两人各自抽3轮范围纸牌。
小童第1轮:抽取第3~5张纸牌,该轮数字和5+3+6=14。
小童第2轮:抽取第6~7张纸牌,该轮数字和4+9=13。
小童第3轮:抽取第2~7张纸牌,该轮数字和10+5+3+6+4+9=37。
小童数字总和14+13+37=64。
小程第1轮:抽取第2~6张纸牌,该轮数字和10+5+3+6+4=28。
小程第2轮:抽取第1~2张纸牌,该轮数字和2+10=12。
小程第3轮:抽取第1~6张纸牌,该轮数字和2+10+5+3+6+4=30。
小程数字总和28+12+30=70。
最终小程数字总和大于小童,输出字符C。

#include<bits/stdc++.h>
using namespace std;
int a[500001],s[500001];
int main(){int n,m;long long sum_t=0,sum_c=0;int L,R;cin>>n>>m;for(int i=1;i<=n;i++){cin>>a[i];s[i]=s[i-1]+a[i]; //计算前缀和}for(int i=1;i<=m;i++){cin>>L>>R;sum_t=sum_t+(s[R]-s[L-1]); //用前缀和计算范围纸牌总和;并累加}for(int i=1;i<=m;i++){cin>>L>>R;sum_c=sum_c+(s[R]-s[L-1]); //用前缀和计算范围纸牌总和;并累加}if(sum_t>sum_c){//小童m轮纸牌总数大cout<<'T';}else if(sum_t<sum_c){//小程m轮纸牌总数大cout<<'C';}else{//平局cout<<'D';}return 0;
}

2918 物资准备

描述

某国测试一种新型火炮,对一条路线进行打击。
这条路线上有n个据点,每个据点都有一个牢固值,1发炮弹消耗1点牢固值,假设牢固值为10的据点,需要10发炮弹摧毁。
现在共有m门火炮参与测试,每门火炮摧毁一段连续范围的据点。
由于指挥混乱,m门火炮发射前没有沟通,可能存在炮弹浪费的情况。
问合计需要准备多少发炮弹。

输入描述

输入描述
第一行包括两个整数n和m。(1≤n,m≤100000)
第二行包括n个整数,依次表示n个据点的牢固值。(1≤整数≤100)
接下来m行,每行两个正整数L和R,表示一门火炮的摧毁范围。(1≤L≤R≤n)

输出描述

输出一个整数,表示炮弹总数。

样例输入 1 

7 2
2 10 5 3 6 4 9
3 5
6 7

样例输出 1 

27

样例输入 2 

5 3
4 2 10 3 7
1 2
4 5
1 3

样例输出 2 

32

提示

样例1解释:

路线上有 7 个据点,2 门火炮参与。
7个据点的牢固值依次为:2,10,5,3,6,4,9。
第1门火炮摧毁第3,4,5据点,需发射炮弹数量:5+3+6=14。
第2门火炮摧毁第6,7据点,需发射炮弹数量:4+9=13。
合计需要准备 27 发炮弹。

样例2解释:

路线上有 5 个据点,3 门火炮参与。
5个据点的牢固值依次为:4,2,10,3,7。
第1门火炮摧毁第1,2据点,需发射炮弹数量:4+2=6。
第2门火炮摧毁第4,5据点,需发射炮弹数量:3+7=10。
第3门火炮摧毁第1,2,3据点,需发射炮弹数量:4+2+10=16。(无需考虑炮弹浪费的情况)
合计需要准备 32 发炮弹。

#include<bits/stdc++.h>
using namespace std;
int a[100010]; //原数据
int s[100010]; //前缀和
int main(){int n,m;cin>>n>>m;//输入原数据for(int i=1;i<=n;i++)	cin>>a[i];//计算前缀和ss[1]=a[1];for(int i=2;i<=n;i++)	s[i]=s[i-1]+a[i];//总数 注意总数会超过int范围,用long long类型long long sum=0;for(int i=1;i<=m;i++){int L,R;cin>>L>>R;sum+=(s[R]-s[L-1]);}cout<<sum;return 0;
}

3212 有趣的求和

描述

给出n个数排成一排,你可以任意选出连续的L个数字求和。例如:
n=5 L = 4
-20 30 80 50 40
连续取L个数的方法有两种。
1、取前4个数-20 30 80 50 和为140。
2、取后4个数30 80 50 40 和为200。
请你找出最大和是多少,上例结果应该为200。

输入描述

第1行为两正整数n和L表示数列数字个数和取的长度;
第2行n个整数空格分隔,表示数列中的每个元素,数字在-100到100之间的整数。

输出描述

输出一个整数,最大的数字和。

样例输入 1 

5 4
-20 30 80 50 40

样例输出 1 

200

提示

数据范围与提示

30%的数据1≤L≤n≤100。
50%的数据1≤L≤n≤10000。
100%的数据 1≤L≤n≤1000000。

#include<bits/stdc++.h>
using namespace std;
int a[1000001],s[1000001];
int main(){int n,l;cin>>n>>l;for(int i=1;i<=n;i++)	cin>>a[i];//计算前缀和s[1]=a[1];for(int i=2;i<=n;i++) s[i]=s[i-1]+a[i];//创建变量存储最大数字和//初始化成比可能出现的最小值还小int max1=-1000000000;for(int i=l;i<=n;i++){if(max1<s[i]-s[i-l])	max1=s[i]-s[i-l];}cout<<max1;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/901616.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL部分总结

mysql学习笔记&#xff0c;如有不足还请指出&#xff0c;谢谢。 外连接&#xff0c;内连接&#xff0c;全连接 外连接&#xff1a;左外、右外 内连接&#xff1a;自己和自己连接 全连接&#xff1a;左外连接右外链接 mysql unique字段 unique可以在数据库层面避免插入相同…

Spring MVC 请求处理流程详解

步骤1&#xff1a;用户发起请求 所有请求首先被 DispatcherServlet&#xff08;前端控制器&#xff09;拦截&#xff0c;它是整个流程的入口。 DispatcherServlet 继承自 HttpServlet&#xff0c;通过 web.xml 或 WebApplicationInitializer 配置映射路径&#xff08;如 /&…

Vue 高级技巧深度解析

Vue 高级技巧深度解析 mindmaproot(Vue2高级技巧)组件通信EventBusprovide/inject$attrs/$listeners性能优化虚拟DOM优化函数式组件按需加载状态管理Vuex模块化持久化存储严格模式高级指令自定义指令动态组件异步组件渲染控制作用域插槽渲染函数JSX支持一、组件通信的进阶之道 …

2024年React最新高频面试题及核心考点解析,涵盖基础、进阶和新特性,助你高效备战

以下是2024年React最新高频面试题及核心考点解析&#xff0c;涵盖基础、进阶和新特性&#xff0c;助你高效备战&#xff1a; 一、基础篇 React虚拟DOM原理及Diff算法优化策略 • 必考点&#xff1a;虚拟DOM树对比&#xff08;同级比较、Key的作用、组件类型判断&#xff09; •…

Zookeeper单机三节点集群部署(docker-compose方式)

前提: 服务器需要有docker镜像zookeeper:3.9.3 或能连网拉取镜像 服务器上面新建文件夹: mkdir -p /data/zk-cluster/{data,zoo-cfg} 创建三个zookeeper配置文件zoo1.cfg、zoo2.cfg、zoo3.cfg,配置文件里面内容如下(三个文件内容一样): tickTime=2000 initLimit=10 …

面试题之数据库-mysql高阶及业务场景设计

最近开始面试了&#xff0c;410面试了一家公司 针对自己薄弱的面试题库&#xff0c;深入了解下&#xff0c;也应付下面试。在这里先祝愿大家在现有公司好好沉淀&#xff0c;定位好自己的目标&#xff0c;在自己的领域上发光发热&#xff0c;在自己想要的领域上&#xff08;技术…

数字内容体验案例解析与行业应用

数字内容案例深度解析 在零售行业头部品牌的实践中&#xff0c;数字内容体验的革新直接推动了用户行为模式的转变。某国际美妆集团通过搭建智能内容中台&#xff0c;将产品信息库与消费者行为数据实时对接&#xff0c;实现不同渠道的动态内容生成。其电商平台首页的交互式AR试…

4.15 代码随想录第四十四天打卡

99. 岛屿数量(深搜) (1)题目描述: (2)解题思路: #include <iostream> #include <vector> using namespace std;int dir[4][2] {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向 void dfs(const vector<vector<int>>& grid, vector<vector<bool&g…

【三维重建与生成】GenFusion:SVD统一重建和生成

标题:《GenFusion: Closing the Loop between Reconstruction and Generation via Videos》 来源&#xff1a;西湖大学&#xff1b;慕尼黑工业大学&#xff1b;上海科技大学&#xff1b;香港大学&#xff1b;图宾根大学 项目主页&#xff1a;https://genfusion.sibowu.com 文章…

Quipus,LightRag的Go版本的实现

1 项目简介 奇谱系统当前版本以知识库为核心&#xff0c;基于知识库可以快构建自己的问答系统。知识库的Rag模块的构建算法是参考了LightRag的算法流程的Go版本优化实现&#xff0c;它可以帮助你快速、准确地构建自己的知识库&#xff0c;搭建属于自己的AI智能助手。与当前LLM…

mysql 8 支持直方图

mysql 8 可以通过语句 ANALYZE TABLE table_name UPDATE HISTOGRAM ON column_name WITH 10 BUCKETS; 生产直方图&#xff0c;解决索引数据倾斜的问题 在之前的mysql5.7的版本上是没有的 参考&#xff1a; MySQL :: MySQL 8.0 Reference Manual :: 15.7.3.1 ANALYZE TABL…

力扣-hot100(最长连续序列 - Hash)

128. 最长连续序列 中等 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1&#xff1a; 输入&#xff1a;nums [100,4,200,…

RCEP框架下eBay日本站选品战略重构:五维解析关税红利机遇

2024年RCEP深化实施背景下&#xff0c;亚太跨境电商生态迎来结构性变革。作为协定核心成员的日本市场&#xff0c;其跨境电商平台正经历新一轮价值重构。本文将聚焦eBay日本站&#xff0c;从政策解读到实操路径&#xff0c;系统拆解跨境卖家的战略机遇。 一、关税递减机制下的…

Unity开发框架:输入事件管理类

开发程序的时候经常会出现更改操作方式的情况&#xff0c;这种时候就需要将操作模式以事件的方式注册到管理输入事件的类中&#xff0c;方便可以随时切换和调用 using System; using System.Collections.Generic; using UnityEngine;/// <summary> /// 记录鼠标事件的的…

【kind管理脚本-2】脚本使用说明文档 —— 便捷使用 kind 创建、删除、管理集群脚本

当然可以&#xff0c;以下是为你这份 Kind 管理脚本写的一份使用说明文档&#xff0c;可作为 README.md 或内部文档使用&#xff1a; &#x1f680; Kind 管理脚本说明文档 本脚本是一个便捷的工具&#xff0c;帮助你快速创建、管理和诊断基于 Kind (Kubernetes IN Docker) 的…

opencv常用边缘检测算子示例

opencv常用边缘检测算子示例 1. Canny算子2. Sobel算子3. Scharr算子4. Laplacian算子5. 对比 1. Canny算子 从不同视觉对象中提取有用的结构信息并大大减少要处理的数据量的一种技术&#xff0c;检测算法可以分为以下5个步骤&#xff1a; 噪声过滤&#xff08;高斯滤波&…

Token安全存储的几种方式

文章目录 1. EncryptedSharedPreferences示例代码 2. SQLCipher示例代码 3.使用 Android Keystore加密后存储示例代码1. 生成密钥对2. 使用 KeystoreManager 代码说明安全性建议加密后的几种存储方式1. 加密后采用 SharedPreferences存储2. 加密后采用SQLite数据库存储1. Token…

MySQL数据库表的约束类型和使用

表完整约束性 约束条件 说明 PRIMARY KEY (PK) 标识该字段为该表的主键&#xff0c;是可以唯一的标识记录&#xff0c;不可以为空 UNIQUENOT NULL (primary key) FOREIGN KEY (FK) 标识该字段为该表的外键&#xff0c;实现表与表之间的关联 (foreign key) NULL …

Java 线程详解 --线程概念、线程池、线程同步与安全机制

一、Java线程的概念 Java 线程的本质&#xff1a;每个线程对应一个操作系统线程&#xff0c;由操作系统调度。JVM 通过调用操作系统 API&#xff08;如 Linux 的 pthread&#xff09;创建线程。 关键点&#xff1a; • 用户态与内核态&#xff1a;线程调度依赖操作系统&#…

PCL 计算点云至平面距离(SIMD加速)

文章目录 一、简介二、实现代码三、实现效果一、简介 SIMD 是一种并行计算模型,其中“单指令”表示处理器在同一时刻执行相同的指令,而“多数据”则表示同一条指令操作多个数据元素(如数组中的多个元素或矩阵中的多个元素)。与传统的串行计算不同,SIMD 能够同时处理多个数…