题目描述
小明在练习绝世武功, n 个练功桩排成一排,一开始每个桩的损伤为 0。
接下来小明会练习 m 种绝世武功,每种武功都会对 [l, r]区间分别造成 [s,e] 的伤害。
这个伤害是一个等差序列。例如 l=1,r=4,s=2,e=8 ,则会对 1−4 号练功桩造成2, 4, 6, 8点损伤。
小明想让你统计一下所有练功桩的损伤的和。
输入描述
第一行输入 n,m,代表练功桩的数量和绝世武功的种类数。
接下来 mm 行输入 44 个整数 l, r, s, e。
1≤n≤107,1≤m≤3×105,1≤l,r≤n1 \leq n \leq 10^7 , 1\leq m \leq 3 \times 10 ^ 5 , 1\leq l, r \leq n1≤n≤107,1≤m≤3×105,1≤l,r≤n
输出描述
输出一个整数代表所有练功桩的损伤和, 题目保证所有输入输出都在 [0,9×1018][0, 9 \times 10^{18}][0,9×1018]
输入
6 2
1 5 2 10
2 4 1 1
输出
33
思路
明明可以直接求和公式的题,一开始竟然想到用差分,以此题警戒自己。
此外,在蓝桥杯比赛中,不用快读可能超时!
代码
void test() throws IOException {
Reader cin = new Reader();
int n = cin.nextInt();
int m = cin.nextInt();
long res = 0;
for(int i = 0; i < m; i++) {
long l = cin.nextLong(), r = cin.nextLong(), s = cin.nextLong(), e = cin.nextLong();
res += ((s+e)*(r-l+1))/2;
}
System.out.println(res);
}
差分代码
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
int m = cin.nextInt();
int[] a = new int[10000006];
for(int i = 0; i < m; i++) {
int l = cin.nextInt();
int r = cin.nextInt();
int s = cin.nextInt();
int e = cin.nextInt();
int d = (e-s) / (r-l);
int sm = s;
a[l] += s;
for(int k = l+1; k <= r; k++) {
sm += d;
a[k] += d;
}
a[r+1] -= sm;
}
long res = 0;
for(int i = 1; i <= n; i++) {
a[i] += a[i-1];
res += a[i];
}
System.out.println(res);
}
1万+

被折叠的 条评论
为什么被折叠?



