• 差分讲解


    差分应用到解决题目中,主要是区间修改的问题。

    如果让你给区间[l,r]中的每一个数都加上x,一般情况下会直接暴力循环将每一个数都加上x。

    就像这样:

    1 void update(int l,int r,int x)
    2 {
    3     for(int i=l;i<=r;i++)
    4     {
    5         a[i]+=x;
    6     }
    7 }

    但是如果l-r非常大的话,这样做很明显时间复杂度很高,而差分则可以解决这个问题。

    首先看一下前缀和的概念,前缀和是前 i 个数的和,就有了前缀和数组presum[maxn],前缀和数组中的每一个元素都存储了对应数组a[maxn]中前 i 个数的和,也就是presum[i]=presum[i-1]+a[i](前i-1个数的和加上当前数)。

    差分可以说是和前缀和操作相反的,差分需要一个差分数组d[maxn],差分数组储存的是相邻元素的差,即d[i]=a[i] -a[i-1]。

    举个例子:比如数组a={1,2,3,4,5,6},那么前缀和数组是presum={1,3,6,10,15,21},差分数组d={1,1,1,1,1}(少一个)。

    构造差分数组的代码:(a数组是编号1-n的数组)

    1 void makediff(int n)
    2 {
    3     for(int i=2;i<=n;i++)
    4     {
    5         d[i]=a[i]-a[i-1];
    6     }
    7 }

    进行区间修改操作,只需要在l和r这两个端点处对差分数组进行修改,假如在区间[l,r],中每个数都加上x。

    那么将d[l]加上x,将d[r+1]减去x,因为是相邻的差,所以数a[r+1]-a[r]是差分数组d[r+1]的值,a[r+1]没变,而a[r]变了,所以..就这样。

    看代码:

    1 void update(int l,int r,int x)
    2 {
    3     d[l]+=x;
    4     d[r+1]-=x;
    5     return ;
    6 }

     要得到一个数a[i],需要推出这个数。

    从第1个数依托差分数组得到每一个a[i],或者直接到要查询的数就停也可以。

    代码如下:

    1 int getnum(int pos)
    2 {
    3     for(int i=1;i<=n;i++)
    4     {
    5         a[i]=a[i-1]+d[i];
    6     }
    7     return a[pos];
    8 }
  • 相关阅读:
    jmeter实现上传文件
    jmeter之调度器设置
    存储过程的几种传参方式
    Charles篡改数据
    软件测试职业发展方向
    最近发现一个有意思的lua游戏引擎,名字叫love2d
    2016,新的一年来到。
    Corona手游教程之widget:Slider篇
    Corona手游教程之widget:PickerWheel篇
    Corona手游教程之widget:ProgressView篇
  • 原文地址:https://www.cnblogs.com/theshorekind/p/12681496.html
Copyright © 2020-2023  润新知