数学——差分序列

个人理解:

差分优化了朴素o(n)进行的区间加和,使得实时询问的时候可以在o(1)内进行

一般朴素的想法应该是下面这样的:

    int a[10005],l,r,k;
    for(int i=l;i<=r;i++){
        a[i]+=k;
    }

差分思想:首先是查分数组的初始化:

    int p[10],a[10]={0,1,2,3,90,5,6,7,8,9};
        //p是a的差分数组 
    for(int i=1;i<=9;i++){
        p[i]=a[i]-a[i-1];
        cout<<p[i]<<" ";
    }

这段代码会输出

输出: 1 1 1 87 -85 1 1 1 1 

那么我们现在就可以进行区间加操作了,代码如下:

int p[10],a[10]={0,1,2,3,90,5,6,7,8,9};
void pl(int l,int r,int k){
    //操作:在[l,r]上加 k
    p[l]+=k,p[r+1]-=k;
        //注意是 r+1 !!! 
    return; 
}

那么当我们要输出数组a的某一个元素要怎么办呢

很简单,通过差分数组p和原来的数组a“倒推”出a[i],代码实现如下

void get_a(){
    for(int i=1;i<=9;i++){
        a[i]=p[i]+a[i-1];
    }
}

理解:

其实这个地方当时想到头元素是否会越界,但写了下发现根本无需多虑,原因如下:

在这里插入图片描述在这里插入图片描述

当然放为全局变量也是同样的输出

在这里插入图片描述
在这里插入图片描述

但是有些oj会爆error,在输出上将循环输出位后移即可

博客借鉴

发布了247 篇原创文章 · 获赞 22 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43658924/article/details/103098183