JAVA文件如何差分,AcWing 797. 差分_java

什么是差分

差分是求前缀和的逆操作,对于原数组a[n],构造出一个数组b[n],使a[n]为b[n]的前缀和。一般用于快速对整个数组进行操作,比如对将a数组中[l,r]部分的数据全部加上c。使用暴力方法的话,时间复杂至少为O(n),而使用差分算法可以将时间复杂度降低到O(1)。

算法思路

拥有数组b[n]后,想要对a数组中所有的数据加上c,只需要将b[1]+c即可,因为a[i]是b[i]的前缀和,a[i]=b[1]+b[1]+b[3]+……+b[n]。b[1]是所有的a[i]都拥有的子元素,将b[0]+c,那么a[n]中所有的数据都会加上c。如果想将a数组中[l,r]部分的数据全部加上c,只需要将b[l]+c,然后b[r+1]-c即可。

差分操作和前缀和一样数组下标都从1开始。

b[l]+c后,l后面的数组都会加c。r后面的数据也会被改变,要改回来就得b[r+1]-c

如何构造b[n]

构造b[n]看起来很难,其实根本就不用刻意去构造它。

如果将a数组中[l,r]部分的数据全部加上c看作一次插入操作,那么构造的过程可以看作是将a进行了n次插入操作。第一次在[1,1]的范围插入了a[1],第二次在[2,2]范围插入a[2],第二次在[3,3]范围插入a[3]……,以此类推,进行n次插入后,那么数组a就正好是数组b的前缀和了。

例题

原题链接

输入一个长度为n的整数序列。

接下来输入m个操作,每个操作包含三个整数l, r, c,表示将序列中[l, r]之间的每个数加上c。

请你输出进行完所有操作后的序列。

输入格式

第一行包含两个整数n和m。

第二行包含n个整数,表示整数序列。

接下来m行,每行包含三个整数l,r,c,表示一个操作。

输出格式

共一行,包含n个整数,表示最终序列。

数据范围

1≤n,m≤100000,

1≤l≤r≤n,

−1000≤c≤1000,

−1000≤整数序列中元素的值≤1000

输入样例:

6 3

1 2 2 1 2 1

1 3 1

3 5 1

1 6 1

输出样例:

3 4 5 3 4 2

java代码

package 差分;

import java.io.BufferedInputStream;

import java.util.Scanner;

public class Main {

static int N = 100010;

public static void main(String[] args) {

Scanner scanner = new Scanner(new BufferedInputStream(System.in));

int n = scanner.nextInt();

int m = scanner.nextInt();

//a为原数组,b为差分数组

int[] a = new int[N];

int[] b = new int[N];

for (int i = 1; i <= n; i++) {

a[i] = scanner.nextInt();

}

//进行n次插入,初始化差分数组

for(int i=1;i<=n;i++) {

insert(b, i, i, a[i]);

}

while(m-->0) {

int l,r,c;

l = scanner.nextInt();

r = scanner.nextInt();

c = scanner.nextInt();

insert(b, l, r, c);

}

//经过一系列插入操作后,现在答案数组应该是b数组的前缀和,让b数组变成b的前缀和。

//公式 b[i] = b[i-1] + b[i]

for(int i=1;i<=n;i++)b[i] +=b[i-1];

for(int i=1;i<=n;i++)System.out.print(b[i]+" ");

System.out.println();

scanner.close();

}

//插入操作函数

public static void insert(int[] a,int l,int r,int c) {

a[l]+=c;

a[r+1]-=c;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值