小明拥有 N个彩灯,第 i 个彩灯的初始亮度为ai。
小明将进行 Q 次操作,每次操作可选择一段区间,并使区间内彩灯的亮度 +x(x 可能为负数)。
求 Q次操作后每个彩灯的亮度(若彩灯亮度为负数则输出 0)。
输入描述
第一行包含两个正整数 N,Q,分别表示彩灯的数量和操作的次数。
第二行包含 N 个整数,表示彩灯的初始亮度。
接下来 Q行每行包含一个操作,格式如下:
l r x
,表示将区间 l∼r 的彩灯的亮度 +x。1≤N,Q≤5×10^5,0≤ai≤10^9,1≤l≤r≤N,−10^9≤x≤10^9
输出描述
输出共 1行,包含 N 个整数,表示每个彩灯的亮度。
输入输出样例
示例 1
输入
5 3 2 2 2 1 5 1 3 3 4 5 5 1 1 -100
输出
0 5 5 6 10
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
看到区间和加x(x可为负数时)很容就想到前几天学习的差分前缀和。开开心心的写了一串代码出来,跑出来了但是挪到提交器上就超时了。
import java.util.Scanner;
public class Main {
static int N=500010;
static int[] a=new int[N];
static int[] b=new int[N];
public static void insert(int l,int r,int x) {
b[l]+=x;
b[r+1]-=x;
}
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int n=in.nextInt();
int m=in.nextInt();
for (int i = 1; i <=n; i++) {
a[i]=in.nextInt();
}
for (int i = 1; i <=n; i++) {
insert(i, i, a[i]);//得到差分后的数组b
}
while (m>0) {
m--;
int l=in.nextInt();
int r=in.nextInt();
int x=in.nextInt();
insert(l, r, x);
}
//复原
for (int i = 1; i <=n; i++) {
b[i]+=b[i-1];
}
for (int i = 1; i <=n; i++) {
if (b[i]<0) {
b[i]=0;
}
System.out.print(b[i]+" ");
}
}
}
好不冤不冤,Scanner虽然很好用,但是它是一个一个读入的,包括了空格所以当输入量和输出量太大的时候(达到百万到千万),这种输入方式效率就很低。
所以查阅了一下大佬们的题解,发现这时候可以用StreamTokenizer类来输入基本数据类型。
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
int b;
in.nextToken();
b = (int)in.nval;
其中in.nextToken()代表输入,遇到空格键,Enter键,Tab键结束一次输入。(XXX)in.nval是将输入的数据转化成自己想要的数据类型(每输入一次转化一次)。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.*;
public class Main {
static int N=500010;
static long[] a=new long[N];
static long[] b=new long[N];
static long n,m;
static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static long nextLong() throws IOException {
in.nextToken();
return (long)in.nval;
}
public static int nextInt() throws IOException{
in.nextToken();
return (int)in.nval;
}
public static void main(String[] args) throws IOException {
n=nextLong();
m=nextLong();
for (int i = 1; i <=n; i++) {
a[i]=nextLong();
b[i]=a[i]-a[i-1];
}
while (m>0) {
m--;
int l,r;
long x;
l=nextInt();
r=nextInt();
x=nextLong();
b[l]+=x;
b[r+1]-=x;
}
StringBuilder s=new StringBuilder(a.length+2);
for (int i = 1; i <=n; i++) {
a[i]=a[i-1]+b[i];
if (a[i]<0) {
s.append(0+" ");
}else {
s.append(a[i]+" ");
}
}
System.out.println(s);
}
}
这里要用long哦,不然测试的样例数字大了会爆。(之前用的int就不行)
谢谢沙雕是沙雕是沙雕的解惑~