前缀和的作用就是快速求一段区间的和!!!
1.一维前缀和
1.模板
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int m = scan.nextInt();
int[] a = new int[n+1];
int[] s = new int[n+1];
for(int i = 1 ; i <= n ; i ++ ){
a[i] = scan.nextInt();
}
for(int i = 1 ; i <= n ; i ++){
s[i] = s[i-1] + a[i];
}
while(m-- > 0){
int l = scan.nextInt();
int r = scan.nextInt();
System.out.println(s[r] - s[l-1]);
}
}
}
2.求和
链接:
前缀和的基础题,常规暴力肯定会超时,可以用前缀和简化,一定要开long,十年oi一场空,不开long long 见祖宗!!!
import java.util.Scanner;
public class Main {
static int N=200010;
static long[]a=new long[N];
static long[]s=new long[N];
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
for (int i = 1; i <=n ; i++) {
a[i]=sc.nextLong();
s[i]=s[i-1]+a[i];
}
long sum=0;
for (int i = 1; i <n ; i++) {
sum+=a[i]*(s[n]-s[i]);
}
System.out.println(sum);
}
}
3.子串简写
本题竟然是一个20分的蓝桥杯B组真题,20分诶还可靠后,拿下20分,省一嘎嘎有希望!!!本题的意思就是给定一个字符串,如果长度大于等于K则可以简写,求以c1开头,c2结尾可以简写的子串有多少? 如果当前c1的字符的下标是i,就是求区间【i+k-1,n】有多少个c2!!! 我们可以用前缀和数组来处理!
package QianZhuiHe;
import java.util.Scanner;
public class 子串简写 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int k=sc.nextInt();
String str=sc.next();
int n=str.length();
str=" "+str;
int[]a=new int[n+1];
int[]s=new int[n+1];
char c1=sc.next().charAt(0);
char c2=sc.next().charAt(0);
for (int i = 1; i <=n ; i++) {
if(str.charAt(i)==c2){
a[i]=1;
}
}
for (int i = 1; i <=n ; i++) {
s[i]=s[i-1]+a[i];
}
int sum=0;
for (int i = 1; i+k-1 <=n ; i++) {
if(str.charAt(i)==c1){
sum+=s[n]-s[i+k-2];
}
}
System.out.println(sum);
}
}
2.二维前缀和
1.子矩阵的和
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int m = scan.nextInt();
int q = scan.nextInt();
int[][] a = new int[n+1][m+1];
int[][] s = new int[n+1][m+1];
for(int i = 1 ; i <= n ; i ++ ){
for(int j = 1 ;j <= m ; j ++ ){
a[i][j] = scan.nextInt();
}
}
for(int i = 1 ; i <= n ; i ++ ){
for(int j = 1 ;j <= m ; j ++ ){
s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + a[i][j];
}
}
while(q-->0){
int x1 = scan.nextInt();
int y1 = scan.nextInt();
int x2 = scan.nextInt();
int y2 = scan.nextInt();
System.out.println(s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] + s[x1-1][y1-1]);
}
}
}