差分

一维差分

"""
# 查分适用场景
给你一串长度为n的数列a1,a2,a3......an,要求对a[L]~a[R]进行m次操作:
操作一:将a[L]~a[R]内的元素都加上P
操作二:将a[L]~a[R]内的元素都减去P

[参考](https://www.jianshu.com/p/fcb68475b5e4)

查分是前缀和的逆运算
原数组:a1, a2, a3, a4
查分数组:b1 = a1
        b2 = a2 - a1
        b3 = a3 - a2
        b4 = a4 - a3
即满足:a1 = b1
       a2 = b1 + b2
       a3 = b1 + b2 + b3
       a4 = b1 + b2 + b3 + b4
"""

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

/*
差分是前缀和的逆运算
原数组:a1, a2, a3, a4
查分数组:b1 = a1
        b2 = a2 - a1
        b3 = a3 - a2
        b4 = a4 - a3
即满足:a1 = b1
       a2 = b1 + b2
       a3 = b1 + b2 + b3
       a4 = b1 + b2 + b3 + b4
*/
var (
    a []int
    b []int
)

func add(l, r, p int) {
    b[l-1] += p
    if r < len(b) {
        b[r] -= p
    }
}

// 对于差分只有一个操作
func main() {
    var reader = bufio.NewReader(os.Stdin)
    var x = readArray(reader)
    a = readArray(reader)
    b = make([]int, x[0])

    // 构造差分数组
    // 题目将1作为下标开始
    for i := 1; i < x[0]+1; i++ {
        add(i, i, a[i-1])
    }

    // 处理操作
    for i := 0; i < x[1]; i++ {
        var op = readArray(reader)
        add(op[0], op[1], op[2])
    }

    // 还原数组
    a[0] = b[0]
    for i := 1; i < x[0]; i++ {
        a[i] = b[i] + a[i-1]
    }
    fmt.Println(nums2string(a, " "))
}

func nums2string(x []int, sep string) string {
    var b strings.Builder
    for i := 0; i < len(x); i++ {
        b.WriteString(strconv.Itoa(x[i]))
        b.WriteString(sep)
    }
    return b.String()
}

func readLine(reader *bufio.Reader) string {
    var line, _ = reader.ReadString('\n')
    return strings.TrimRight(line, "\n")
}

func readInt(reader *bufio.Reader) int {
    var num, _ = strconv.Atoi(readLine(reader))
    return num
}

func readArray(reader *bufio.Reader) []int {
    var line = readLine(reader)
    var strList = strings.Split(line, " ")
    var nums = make([]int, 0)
    var err error
    var v int
    for i := 0; i < len(strList); i++ {
        if v, err = strconv.Atoi(strList[i]); err != nil {
            continue
        }
        nums = append(nums, v)
    }
    return nums
}

/*
输入一个长度为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
*/

二维差分

go

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

var (
    a  [][]int
    b  [][]int
    lx int
    ly int
)

func add(x1, y1, x2, y2, p int) {
    b[x1-1][y1-1] += p
    b[x1-1][y2] -= p
    b[x2][y1-1] -= p
    b[x2][y2] += p
}

func main() {
    var reader = bufio.NewReader(os.Stdin)
    var x = readArray(reader)
    lx = x[0]
    ly = x[1]

    // 原数组
    a = make([][]int, x[0])
    for i := 0; i < x[0]; i++ {
        a[i] = readArray(reader)
    }
    // 初始化差分数组
    b = make([][]int, x[0] + 1)
    // 前缀和数组
    var sums = make([][]int, x[0] + 1)
    for i := 0; i < x[0] + 1; i++ {
        b[i] = make([]int, x[1] + 1)
        sums[i] = make([]int, x[1] + 1)
    }
    // 构造差分数组
    for i := 0; i < x[0]; i++ {
        for j := 0; j < x[1]; j++ {
            add(i+1, j+1, i+1, j+1, a[i][j])
        }
    }
    // 处理操作
    for i := 0; i < x[2]; i++ {
        var op = readArray(reader)
        add(op[0], op[1], op[2], op[3], op[4])
    }
    // 还原数组
    sums[0][0] = b[0][0]
    for i := 1; i < x[0]; i++ {
        sums[i][0] = sums[i-1][0] + b[i][0]
    }
    for i := 1; i < x[1]; i++ {
        sums[0][i] = sums[0][i-1] + b[0][i]
    }
    //sums[1][0] = b[1][0] + b[0][0]
    //sums[0][1] = b[0][1] + b[0][0]
    for i := 1; i < x[0] + 1; i++ {
        for j := 1; j < x[1] + 1; j++ {
            sums[i][j] = sums[i][j-1] + sums[i-1][j] + b[i][j] - sums[i-1][j-1]
        }
    }
    for i := 0; i < x[0]; i++ {
        fmt.Println(nums2string(sums[i][:x[1]], " "))
    }
}

func nums2string(x []int, sep string) string {
    var b strings.Builder
    for i := 0; i < len(x); i++ {
        b.WriteString(strconv.Itoa(x[i]))
        b.WriteString(sep)
    }
    return b.String()
}

func readLine(reader *bufio.Reader) string {
    var line, _ = reader.ReadString('\n')
    return strings.TrimRight(line, "\n")
}

func readInt(reader *bufio.Reader) int {
    var num, _ = strconv.Atoi(readLine(reader))
    return num
}

func readArray(reader *bufio.Reader) []int {
    var line = readLine(reader)
    var strList = strings.Split(line, " ")
    var nums = make([]int, 0)
    var err error
    var v int
    for i := 0; i < len(strList); i++ {
        if v, err = strconv.Atoi(strList[i]); err != nil {
            continue
        }
        nums = append(nums, v)
    }
    return nums
}

/*
输入一个n行m列的整数矩阵,再输入q个操作,每个操作包含五个整数x1, y1, x2, y2, c,其中(x1, y1)和(x2, y2)表示一个子矩阵的左上角坐标和右下角坐标。

每个操作都要将选中的子矩阵中的每个元素的值加上c。

请你将进行完所有操作后的矩阵输出。

输入格式
第一行包含整数n,m,q。

接下来n行,每行包含m个整数,表示整数矩阵。

接下来q行,每行包含5个整数x1, y1, x2, y2, c,表示一个操作。

输出格式
共 n 行,每行 m 个整数,表示所有操作进行完毕后的最终矩阵。

数据范围
1≤n,m≤1000,
1≤q≤100000,
1≤x1≤x2≤n,
1≤y1≤y2≤m,
−1000≤c≤1000,
−1000≤矩阵内元素的值≤1000
输入样例:
3 4 3
1 2 2 1
3 2 2 1
1 1 1 1
1 1 2 2 1
1 3 2 3 2
3 1 3 4 1
输出样例:
2 3 4 1
4 3 4 1
2 2 2 2
*/

python

class Solution(object):

    def __init__(self, matrix):
        self.m = len(matrix) + 1
        self.n = len(matrix[0]) + 1

        x = len(matrix) + 10
        y = len(matrix[0]) + 10
        self.nums = [[0] * y for _ in range(x)]

        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                self.add(i + 1, j + 1, i + 1, j + 1, matrix[i][j])

    def add(self, x1, y1, x2, y2, c):
        self.nums[x1][y1] += c
        self.nums[x2 + 1][y1] -= c
        self.nums[x1][y2 + 1] -= c
        self.nums[x2 + 1][y2 + 1] += c

    def query(self):
        ans = [[0] * self.n for _ in range(self.m)]
        for i in range(1, self.m):
            for j in range(1, self.n):
                ans[i][j] = ans[i][j - 1] + ans[i - 1][j] - ans[i - 1][j - 1] + self.nums[i][j]
        # print(ans)
        for xx in ans[1:]:
            print(" ".join([str(x) for x in xx[1:]]))


if __name__ == '__main__':
    n, m, q = [int(x) for x in input().split(" ")]
    xx = [[0] * m for _ in range(n)]
    for i in range(n):
        xx[i] = [int(x) for x in input().split(" ")]
    S = Solution(xx)
    for _ in range(q):
        qq = [int(x) for x in input().split(" ")]
        S.add(qq[0], qq[1], qq[2], qq[3], qq[4])
    S.query()

最后更新于

这有帮助吗?