目录
  1. 1. 一维前缀和
    1. 1.1. 题目描述
      1. 1.1.0.1. 输入格式
      2. 1.1.0.2. 输出格式
      3. 1.1.0.3. 数据范围
  2. 1.2. 题目分析
  3. 1.3. 代码实现
  4. 1.4. 运行结果
  5. 1.5. 总结
  • 2. 二维前缀和
    1. 2.1. 题目描述
      1. 2.1.0.1. 输入格式
      2. 2.1.0.2. 输出格式
      3. 2.1.0.3. 数据范围
  • 2.2. 题目分析
  • 2.3. 代码实现
  • 2.4. 运行结果
  • 2.5. 总结
  • 前缀和

    一维前缀和

    题目描述

    输入一个长度为n的整数序列。
    接下来再输入m个询问,每个询问输入一对l, r。
    对于每个询问,输出原序列中从第$l$个数到第$r$个数的和。

    输入格式

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

    输出格式

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

    数据范围

    $1<=l<=r<=n$

    $1<=n,m<=100000$

    $-1000<=$数列中元素的值$<=1000$

    题目分析

    此类题可以推算出一种公式。

    代码实现

    #include<bits/stdc++.h>

    using namespace std;
    const int N = 100010;

    int n, m;
    int a[N], s[N];
    int main(){
    // 分别输入序列长度n 与 访问次数 m
    scanf("%d %d", &n, &m);
    // 输入整数序列,从1开始
    for(int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
    // 初始化前缀和,从1开始
    for(int i = 1; i <= n; i++)
    s[i] = s[i - 1] + a[i];

    // 依次输入询问对
    while(m --){
    int l, r;
    scanf("%d %d", &l, &r);
    printf("%d\n", s[r] - s[l - 1]);
    }

    return 0;
    }

    运行结果

    输入

    6 3
    1 2 3 4 5 6
    1 2
    1 4
    2 5

    输出

    3
    10
    14

    总结

    求前缀和,主要考虑区间端点,根据推算的公式可以将其直接运用,需要注意的是$S_0=0$此处要控制边界。

    二维前缀和

    题目描述

    输入一个n行m列的整数矩阵,再输入q个询问,每个询问包含四个整数x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。

    输入格式

    第一行包含三个整数n, m,q。
    接下来n行,每行包含m个整数,表示整数矩阵。
    接下来q行,每行包含四个整数x1,y1,x2,y2,表示一组询问。

    输出格式

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

    数据范围

    $1<=n,m<=1000$

    $1<=q<=100000$

    $1<=x_1<=x_2<=n$

    $1<=y_1<=y_2<=m$

    $-1000<=$矩阵内元素的值$<=1000$

    题目分析

    此类题可以推算出一种公式。

    代码实现

    #include<bits/stdc++.h>

    using namespace std;
    const int N = 1010;

    int n, m, q;
    int a[N][N], s[N][N];
    int main(){
    // 分别输入序列长度n 与 访问次数 m
    scanf("%d %d %d", &n, &m, &q);
    // 输入整数矩阵
    for(int i = 1; i <= n; i++)
    for(int j = 1; j <= m; j++)
    scanf("%d", &a[i][j]);
    // 初始化矩阵前缀和
    for(int i = 1; i <= n; i++)
    for(int j = 1; j <= m; j++)
    s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + a[i][j];

    // 依次输入询问对
    while(q --){
    int x1 ,y1, x2, y2;
    scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
    printf("%d\n", s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1]); // 算子矩阵的和
    }

    return 0;
    }

    运行结果

    输入

    3 4 3
    1 7 2 4
    3 6 2 8
    2 1 2 3
    1 1 2 2
    2 1 3 4
    1 3 3 4

    输出

    17
    27
    21

    总结

    矩阵序列同样可以通过一维类似的方式进行解决,通过分析图解推导公式最后代入公式即可

    文章作者: Jachie Xie
    文章链接: https://xjc5772.github.io/2020-08/30/%E7%AE%97%E6%B3%95/%E7%AE%97%E6%B3%95%E5%9F%BA%E7%A1%80/%E5%89%8D%E7%BC%80%E5%92%8C%E4%B8%8E%E5%B7%AE%E5%88%86/%E5%89%8D%E7%BC%80%E5%92%8C/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 XJC&Blog
    打赏
    • 微信
    • 支付宝

    评论