小明的彩灯

小明拥有 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就不行)

谢谢沙雕是沙雕是沙雕的解惑~

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值