目录
}for(int i=1;i<=n;i++) c[i]=c[i-1]+b[i];
基础:
字符串输入:
sc.nextLine();//扫描空行
String s=sc.nextLine();
区间修改问题
给定一个长度为 n 的序列 a.
再给定 m 组操作,每次操作给定 3 个正整数l,r,d,表示对 al~r中的所有数增加d。
最终输出操作结束后的序列 a。
暴力做法为写一个循环,每次修改l~r之间的所有数字。
时间复杂度最坏为O(nm)。
一维差分实现原理
定义差分数组 b, bi= ai — ai-1。
b1= a1
b2 = a2 — a1
b3 = a3 - a2
b4= a4 -a3。
我们对数组 b求前缀和得到新数组 c。
c1 = b1 = a1 = a1
c2 = b1 + b2 = a1 + a2 - a1= a2
c3 = b1 + b2 + b3 = a1 + a2 - a1+ α3 - a2 = a3
c4 = b1 + b2 + b3 + b4 =a1 + a2 -a1 + a3 - a2 + a4 - a3 = a4
我们能得到一个结论,差分数组求前缀和得出的就是原数组。
我们现在将b1 +1。再去求一个前缀和数组。
c1 = b1 + 1 = a1 + 1 = a1+1
c2 = b1 + 1 + b2 = a1 + a2 -a1 + 1 = a2+ 1
c3 = b1 + 1 + b2 + b3 = a1 + a2 - a1 + a3 - a2 + 1 = a3 + 1
c4= b1+1+b2 +b3+b4 = a1+a2-a1+a3-a2+a4-a3 +1 = α4+1
我们再将b4-1。再去求一个前缀和数组。
c1= b1+1 =a1 +1 = a1+1
c2 = b1 + 1 + b2 = a2 + 1 + a2 - a1= a2+ 1
c3 = b1+ 1 + b2 + b3 =ar+1 + a2 -a1 + a3 - a2 = a3 + 1
c4 = b1+ 1 + b2 + b3 + b4- 1 = a1 + 1 + a2 -a1 + a3 - a2 + a4-a3 -1 = a4
因此,对差分数组 b。将bl+ d, b(r+1)-d,求解前缀和后,即可得到修改后的数组 c.
这种做法的复杂度为 O(n+m)。
差分数组常见性质:
如果差分数组除了b1 以外所有值均为0,则说明数组a的值全部一样。
例题:一维差分
static int N=(100010);
static int a[]=new int[N],b[]=new int[N],c[]=new int[N];
static void solve(){
int n=in.nextInt(),m=in.nextInt();
for(int i=1;i<=n;i++) a[i]=in.nextInt();
for(int i=l;i<=n;i++) b[i]-a[i]-a[i-1];
for(int i=1;i<=m;i++){
int l=in.nextInt(),r=in.nextInt(),d=in.nextInt();
b[l]=b[l]+d;
b[r+1]=b[r+1]-d;
}
for(int i=1;i<=n;i++) c[i]=c[i-1]+b[i];
for(int i=l;i<=n;i++) out.print(c[i]+"");
}
例题:小蓝的操作
代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;
public class Main{
static int N=100010;
static int a[]=new int[N], b[]=new int[N];
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int n=in.nextInt();
long res=0;
for(int i=1;i<=n;i++) {
a[i] = in.nextInt();
b[i]=a[i]-a[i-1];
if(b[i]>0){
res=res+b[i];
}
}
System.out.println(res-1);
}}