前缀和
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,差分(模板)
目录
题目描述
给定一个长度为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;
}