题目背景
语文考试结束了,成绩还是一如既往地有问题。
题目描述
语文老师总是写错成绩,所以当她修改成绩的时候,总是累得不行。她总是要一遍遍地给某些同学增加分数,又要注意最低分是多少。你能帮帮她吗?
输入格式
第一行有两个整数 nn,pp,代表学生数与增加分数的次数。
第二行有 nn 个数,a_1 \sim a_na1∼an,代表各个学生的初始成绩。
接下来 pp 行,每行有三个数,xx,yy,zz,代表给第 xx 个到第 yy 个学生每人增加 zz 分。
输出格式
输出仅一行,代表更改分数后,全班的最低分。
输入输出样例
输入 #1复制
3 2 1 1 1 1 2 1 2 3 1
输出 #1复制
2
说明/提示
对于 40\%40% 的数据,有 n \le 10^3n≤103。
对于 60\%60% 的数据,有 n \le 10^4n≤104。
对于 80\%80% 的数据,有 n \le 10^5n≤105。
对于 100\%100% 的数据,有 n \le 5\times 10^6n≤5×106,p \le np≤n,学生初始成绩 \le 100≤100,z \le 100z≤100。
差分数组的定义:
来看一个例子:
原数组a:5,8,4,3,15
差分数组 b:5,3,−4,−1,12
差分数组就是原数组对应项和它前面那项的差值。
这里会有一个性质:
原数组中的第i项就等于:前i项之和
这是显然的。
差分前缀和
还是先来看例子:
原数组:a:5,8,4,3,15
它的前缀和数组:c:5,13,17,20,35(前缀和就是第i项为原数组前i项之和)
它的差分数组:b:5,3,−4,−1,12(差分数组就是原数组对应项和它前面那项的差值)
它的差分前缀和(就是差分数组的前缀和):d:5,8,4,3,15
(该题主要利用差分数组的性质来优化时间复杂度)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main{
public static void main(String[] args) throws IOException {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
int n,p;
int x,y,z;
st.nextToken();
n = (int) st.nval;//n个学生
//c为差分数组
int c[] = new int [n + 5];//取c的数组长度为n+5是为了防止越位
st.nextToken();
p = (int) st.nval;
int tmp1,tmp2;
tmp1 = 0;
//1,0,0
for(int i = 1; i <= n; i++){
st.nextToken();
tmp2 = (int) st.nval;
if(i == 1) {
c[i] = tmp2;
tmp1 = tmp2;
continue;
}
c[i] = tmp2 - tmp1;//
tmp1 = tmp2;
}
for(int i = 0; i < p; i++){//p次修改
st.nextToken();
x = (int) st.nval;
st.nextToken();
y = (int) st.nval;
st.nextToken();
z = (int) st.nval;
c[x] += z;//
c[y+1] -= z;
}
//差分数组
//2,0,-1
//2,1,-1
//实际分数:2,3,2
int Min = c[1];
for(int i= 2;i <= n;i++){
c[i] += c[i-1];
if(c[i]< Min) Min=c[i];
}
System.out.println(Min);
}
}