两个吃奶一个添下面视频_人妻第一页香蕉网_欧美xxxx少妇_妺妺窝人体色www婷婷

說到差分,差分是一種和前綴和相對的策略,可以當做是求和的逆運算。差分,一般在大數(shù)據里用在以時間為統(tǒng)計維度的分析中,其實就是下一個數(shù)值 ,減去上一個數(shù)值 。當間距相等時,用下一個數(shù)值,減去上一個數(shù)值 ,就叫“一階差分”,做兩次相同的動作,即再在一階差分的基礎上用后一個數(shù)值再減上一個數(shù)值一次,就叫“二階差分"。

本篇我們可以通過代碼實例進行分析和理解。


一、差分

差分是求前綴和的逆操作,類似于數(shù)學中的求導和積分,對于原數(shù)組a[n],構造出一個數(shù)組b[n],使a[n]為b[n]的前綴和。一般用于快速對整個數(shù)組進行操作,比如對將a數(shù)組中[l,r]部分的數(shù)據全部加上c。使用暴力方法的話,時間復雜至少為O(n),而使用差分算法可以將時間復雜度降低到O(1)。


二、差分的介紹與運用

(1)一維差分

創(chuàng)建一數(shù)組b,使得數(shù)組a為數(shù)組b的前綴和,數(shù)組b為數(shù)組a的差分

構造方法:b[i] = a[i] - a[i - 1]

此處使用了一個虛擬的構造方式(在數(shù)組一個位置加上一個數(shù),那么在它的下一個位置減去這一數(shù))

應用:對于a數(shù)組的任意區(qū)間[l, r],令其加上一個數(shù),而不改變其它值

b[l] += c, b[r + 1] -= c

差分操作和前綴和一樣數(shù)組下標都從1開始。

b[l]+c后,l后面的數(shù)組都會加c。r后面的數(shù)據也會被改變,要改回來就得b[r+1]-c


模板題如下:

輸入一個長度為 n 的整數(shù)序列。接下來輸入 m 個操作,每個操作包含三個整數(shù) l,r,c,表示將序列中 [l,r] 之間的每個數(shù)加上 c。

請你輸出進行完所有操作后的序列。

輸入格式

第一行包含兩個整數(shù) n 和 m。

第二行包含 n 個整數(shù),表示整數(shù)序列。

接下來 m 行,每行包含三個整數(shù) l,r,c,表示一個操作。

輸出格式

共一行,包含 n 個整數(shù),表示最終序列。

數(shù)據范圍

1≤n,m≤100000,

1≤l≤r≤n,

?1000≤c≤1000,

?1000≤整數(shù)序列中元素的值≤1000

輸入樣例:

6 3

1 2 2 1 2 1

1 3 1

3 5 1

1 6 1

輸出樣例:

3 4 5 3 4 2


代碼實現(xiàn)如下:

#include <iostream>
using namespace std;
const int N = 1e6+10;
int a[N],b[N];
int main()
{
    int n,m;
    cin>>n>>m;
    for (int i = 1; i <= n; i ++ )cin>>a[i];

    for (int j = 1; j <= n; j ++ )
    {
        b[j]=a[j]-a[j-1];
    }
    while (m -- )
    {
        int l,r,c;
        cin>>l>>r>>c;
        b[l]=b[l]+c;
        b[r+1]=b[r+1]-c;
    }
    int sum=0;
    for (int i = 1; i <= n; i ++ )
    {
        
        sum=sum+b[i];
    cout<<sum<<" ";
    }
    return 0;
}


(2)二維差分

公式:b[i][j] += c, b[i + 1][j] -= c, b[i][j + 1] -= c, b[i + 1][j + 1] += c

每次對b數(shù)組執(zhí)行以上操作,等價于:

for(int i=x1;i<=x2;i++)
  for(int j=y1;j<=y2;j++)
    a[i][j]+=c;

模板題如下

輸入一個 n 行 m 列的整數(shù)矩陣,再輸入 q 個操作,每個操作包含五個整數(shù) x1,y1,x2,y2,c,其中 (x1,y1) 和 (x2,y2) 表示一個子矩陣的左上角坐標和右下角坐標。

每個操作都要將選中的子矩陣中的每個元素的值加上 c。

請你將進行完所有操作后的矩陣輸出。

輸入格式

第一行包含整數(shù) n,m,q。

接下來 n 行,每行包含 m 個整數(shù),表示整數(shù)矩陣。

接下來 q 行,每行包含 5 個整數(shù) x1,y1,x2,y2,c,表示一個操作。

輸出格式

共 n 行,每行 m 個整數(shù),表示所有操作進行完畢后的最終矩陣。

數(shù)據范圍

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


代碼實現(xiàn)如下:

#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1e3 + 10;
int a[N][N], b[N][N];
void insert(int x1, int y1, int x2, int y2, int c)
{
    b[x1][y1] += c;
    b[x2 + 1][y1] -= c;
    b[x1][y2 + 1] -= c;
    b[x2 + 1][y2 + 1] += c;
}
int main()
{
    int n, m, q;
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> a[i][j];
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            insert(i, j, i, j, a[i][j]);      //構建差分數(shù)組
        }
    }
    while (q--)
    {
        int x1, y1, x2, y2, c;
        cin >> x1 >> y1 >> x2 >> y2 >> c;
        insert(x1, y1, x2, y2, c);
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];  //二維前綴和
        }
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
           cout<<b[i][j];
        }
        cout<<endl;
    }
    return 0;
}


點贊(0)

C語言網提供由在職研發(fā)工程師或ACM藍橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習題和答疑,點擊了解:

一點編程也不會寫的:零基礎C語言學練課程

解決困擾你多年的C語言疑難雜癥特性的C語言進階課程

從零到寫出一個爬蟲的Python編程課程

只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程

信息學奧賽或C++選手的 必學C++課程

藍橋杯ACM、信息學奧賽的必學課程:算法競賽課入門課程

手把手講解近五年真題的藍橋杯輔導課程

Dotcpp在線編譯      (登錄可減少運行等待時間)