一维前缀和

1.问题

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

接下来再输入 m 个询问,每个询问输入一对 l,r。

对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。

输入格式

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

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

接下来 m 行,每行包含两个整数 l 和 r,表示一个询问的区间范围。

输出格式

共 m行,每行输出一个询问的结果。

数据范围

1≤l≤r≤n1≤𝑙≤𝑟≤𝑛,
1≤n,m≤1000001≤𝑛,𝑚≤100000,
−1000≤数列中元素的值≤1000

输入样例:

5 3
2 1 3 6 4
1 2
1 3
2 4
输出样例:
3
6
10

2.思路

思路1:每次求l,r的和,我们从下标l开始循环到下标r结束,把循环过程中的值加起来;

下标l开始循环到下标r的循环次数最多n,我们又要进行m组询问,所以

时间复杂度:O(n*m)

代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //数组的长度
        int n = sc.nextInt();
        
        //询问的次数
        int m = sc.nextInt();

        //存储的输入的数组
        int[]a = new int[1000010];
        
        //输入n个数
        for(int i=1;i<=n;i++){
            a[i]=sc.nextInt();
        }
        
        //循环m次,输入l,r
       for(int i=1;i<=m;i++){
           int l = sc.nextInt();
           int r = sc.nextInt();
           
           //存储累加结果
           int sum = 0;
           //从l开始遍历到r,累加a[j]
           for(int j=l;j<=r;j++){
               sum+=a[j];
           }
           
           //输出这次询问的结果
           System.out.println(sum);
       }
    }
}

思路2:如果我们知道从 [1,l-1]的和 以及 [1,r]的和,[1,r]的和 减去  [1,l-1]的和,不就能不循环就得到每组[l,r]区间的和吗?

那么我们如何得出[1 , l-1]和[1 , r]的和呢?

我们将问题一般化,我们要得出的是 [1,i]的和 ,i>=1

我们可以用一个数组sum[i]表示 [1,i]的和,我们找规律,不难发现sum[i]=sum[i-1]+a[i];

也就是从1到i的和 等于 从1到i-1的和 加上 数组当前第i个数a[i]

所以我们只需遍历数组a,就可以得到sum[i]了。

遍历数组a的时间复杂度在O(n),对于m次询问得到sum[r]-sum[l-1]的时间复杂度是O(m),

所以最终时间复杂度在O(Max(n,m))

代码

        //存储的输入的数组
        int[]a = new int[1000010];
        
        //sum[i]表示 [1,i]的和
        int[]sum = new int[1000010];
        
        //循环输入数据a[i],并得到sum[i]
        for(int i=1;i<=n;i++){
            a[i]=sc.nextInt();
            sum[i]=sum[i-1]+a[i];
        }
        
        //循环m次,输入l,r
       for(int i=1;i<=m;i++){
           
            //求和区间的左端点下标
            int l = sc.nextInt();
            
            //求和区间的左端点下标
            int r = sc.nextInt();
            
            
            //输出这次询问的结果 从[1,r]的和减去从[1,l-1]的和得到[l,r]的和
           System.out.println(sum[r]-sum[l-1]);
            
       }
    }
}

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值