算法基础第二次作业(前缀和与差分)

前缀和

1,前缀和(模板)

P1347 - 前缀和(模板) - HAUEOJ (haueacm.top)

题目描述

给定一个长度n的整数序列,然后进行m次询问,对于每次询问给定一个区间[l,r],请求出每次询问的区间中所有整数的和

输入

第一行两个正整数n,m
第二行n个整数
接下来的m行,每行两个数l,r表示询问的区间范围
1≤n≤3e5
1≤m≤1e5

输出

对于每次询问,输出区间和

样例输入 

6 3
1 2 3 4 5 6
1 1
1 5
2 6

样例输出 

1
15
20

 

#include <iostream>
using namespace std;
const int N=300010; 
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;
}

2,子矩阵的和

P1364 - 子矩阵的和 - HAUEOJ (haueacm.top)

题目描述

给定一个 n 行 m 列的二维数组 num,有 q 次询问,对于每次询问,给定两个坐标 P1(x1, y1),P2(x2, y2),求以 P1 为左上角,P2 为右下加的子矩阵的元素之和。

输入

第一行,三个整数 n,m,q

接下来 n 行 m 列,输入 num[i]

接下来 q 行,每行四个整数 x1, y1, x2, y2

输出

共 q 行,每行输出一个整数

样例输入 复制

3 3 2
1 2 3
1 2 3
1 2 3
1 1 2 2
2 2 3 3

样例输出 复制

6
10

提示

10 <= n,m, x1 <= x2, y1 <= y2 <= 500
10 <= q <= 20000

#include <iostream>
using namespace std;
const int N =2010;
int n,m,q;
int a[N][N],s[N][N];
int main(){
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	scanf("%d",&a[i][j]);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];//子矩阵前缀和计算
	while(q--){
		int x1,x2,y1,y2;
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		printf("%d\n",s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]);
	}
	return 0;
}

 其实写多了,多个操作循环可以写成一个循环

3,这是什么招新

P1365 - 这是什么招新 - HAUEOJ (haueacm.top)

题目描述

alexya是一位大一新生并且非常喜欢二次元,在学校的某一天晚自习上,他看到一群女装大佬走进了教室,这让他非常兴奋,但经过大佬们解释他才得知,原来是学校的ACM团队又双
叒来招新了,虽然初来乍到的alexya不知了解ACM是什么东西(他觉得可能是某种cosplay俱乐部),但是一位学长的cos深受alexya的喜爱,为了能再次见到这位学长,alexya决定加入ACM
团队,但是ACM招新有一个要求,就是会不定期的检查你在学校oj上前一周的做题情况,alexya非常不解为什么一个cosplay俱乐部会要求新生做编程,况且自己在这方面是蒟蒻一枚但
是为了学长,alexya决定从第二天开始拼命刷题,恰巧,因为ACM也是从招新的第二天开始记录,并且明确表示了会在一周后的某一天对前一周的做题情况进行统计,所以alexya想知道自己
从第x天开始计算前一周的刷题数量,你能帮助他吗?

输入

第一行两个整数,表示刷题天数n和询问次数t
第二行n个整数,第i个整数表示第i天的刷题数ai
第n+2~n+t+1行一个整数x,表示XX询问的第x天
7<n,t<=1e5
0<ai<100

输出

输出t行一个整数表示每次询问时前一周的刷题数量

样例输入 复制

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

样例输出 复制

28
35
#include <iostream>
using namespace std;
const int N=100010; 
int n,t;
int a[N],s[N];
int main(){
	scanf("%d %d",&n,&t);
	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(t--){
		int x;
		scanf("%d",&x);
		if(x>7) 
		printf("%d\n",s[x-1]-s[x-8]);
		else
		printf("%d\n",s[x-1]);
	}
	return 0;
}

4,来,骗

P1366 - 来,骗 - HAUEOJ (haueacm.top)

题目描述

众所周知,狮均国内吼叫总值(Real GDS per lion)是衡量一个狮子国狮子健康程度的重要指标。
其计算方法为:选取若干个狮子,将每个狮子吼叫的次数相加即为总值。
叶子是狮子国健康委员会的会长,有人举报小林汇报的狮均国内吼叫总值的数据有误,所以他想请你帮忙计算。
具体来说,你会知道编号为 1 到 n 的 n 只狮子吼叫的次数 ai。
叶子会提出 q 个问题。对于每个问题他会给出 l 和 r。
他想知道编号在 l 和 r 之间的狮子的狮均国内吼叫总值。

输入

第一行一个整数 n,代表狮子的数量。
第二行 n 个整数 ai,代表编号为 i 的狮子的吼叫次数。
第三行一个整数 q,代表叶子的问题数。
第四到第 3+q 行,每行两个整数 l,r。
50% 的数据 q=1;
100% 的数据: 1≤n≤106,1≤ai≤103,1≤q≤105,1≤l≤r≤n。

输出

q 行整数,代表计算出来的狮均国内吼叫总值。

样例输入 复制

5
4 1 2 3 5
5
1 1
1 4
2 3
4 5
1 5

样例输出 复制

4
10
3
8
15
#include <iostream>
using namespace std;
const int N=1e6+10; 
int n,q;
int a[N],s[N];
int main(){
	scanf("%d",&n);
	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];
	scanf("%d",&q);
	for(int i=q;i>=1;i--)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",s[r]-s[l-1]);
	}
	return 0;
}

 差分

5,差分(模板)

目录

1,前缀和(模板)

2,子矩阵的和

3,这是什么招新

4,来,骗

5,差分(模板)


题目描述

给定一个长度为n的整数序列,对它进行m次操作,每次选择一个区间[l,r],将区间中的每一个数增加x,求经过m次操作之后的整数序列

输入

第一行两个正整数n,m
第二行n个整数
接下来的m行,每行三个整数l,r,x,如题所示
1≤n≤3e5
1≤m≤1e5
1≤x≤1e3

输出

一行n个整数

样例输入 

6 3
1 2 3 4 5 6
1 6 1
2 3 -1
3 3 6

样例输出 

2 2 9 5 6 7 
#include <iostream>
using namespace std;
const int N=300010;
int n,m;
int a[N],b[N];
void insret(int l,int r,int c){
	b[l]+=c;
	b[r+1]-=c;
}
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++)
	insret(i,i,a[i]);
	while(m--){
		int l,r,c;
		scanf("%d%d%d",&l,&r,&c);
		insret(l,r,c);
	}
	for(int i=1;i<=n;i++)
	b[i]+=b[i-1];
	for(int i=1;i<=n;i++)
	printf("%d ",b[i]);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法第一深情

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值