前缀和与差分

1.前缀和与差分:

前缀和是指某数列的前n项和;差分是前缀和的逆运算。

用数学语言表示:前缀和:a[ n ] = b[ 0 ] + b[ 1 ] + b[ 2 ] + ... + b[ n ];

差分:b[ n ] = a[ n ] - a[ n - 1 ]

差分实例:P2367 语文成绩 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 一个简洁经典的差分题,显著的特征是要对连续的数执行相同的操作。

#include <stdio.h>

int diff_array[5000000];
int main()
{
    int num_of_students, num_of_operations;

    scanf("%d %d", &num_of_students, &num_of_operations);
    for (int i = 0, front = 0; i < num_of_students; ++i)
    {
        scanf("%d", &diff_array[i]);
        diff_array[i] -= front;
        front += diff_array[i];
    }

    for (int i = 0; i < num_of_operations; ++i)
    {
        int x, y, z;
        scanf("%d %d %d", &x, &y, &z);
        diff_array[x - 1] += z;
        diff_array[y] -= z;
    }

    int minimum = diff_array[0];
    int sum = minimum;
    for (int i = 1; i < num_of_students; ++i)
    {
        sum += diff_array[i];
        if (sum < minimum)
        {
            minimum = sum;
        }
    }

    printf("%d\n", minimum);
    system("pause");
    return 0;
}

2.优点:

前缀和可以方便的求数列某一区间的和,时间复杂度从O(n)优化为O(1)。例如求数列{b[n]}的l到r项元素之和:answer = a[ r ] - a[ r ];

差分可以方便的让数列某一区间的元素加上或减少同一个数。时间复杂度从O(n)优化至O(1)。例如数列{a[n]}的l到r项同时加t:b[ l ] += t; b[ r + 1 ] -= t。由于b[ l ] += t后会使数列{a[ n ]}的l及以后的项都加t,故要在b[ r + 1 ]处再减回来。

3.二维前缀和与二维差分

1.二维前缀和:a[n][m]=\sum_{i=0}^{n}\sum_{j=0}^{m}b[i][j]

则左上角b[x1][y1]右下角b[x2][y2]为方阵的元素之和为:answer = a[x2][y2] - a[x2][y1] - a[x1][y2] + a[x1][y1]

二维前缀和的构造:a[n][m]=a[n][m-1]+b[n][m]+a[n-1][m]-a[n-1][m-1]

2.二维差分:b[n][m]=a[n][m]-a[n-1][m]-a[n][m-1]+a[n-1][m-1]

如果希望矩阵内的元素加t:b[x1][y1]+=t; b[x1+1][y1]-=t; b[x1][y1+1]-=t; b[x1+1][y1+1]+=t;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值