国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

一文帶你深入了解算法筆記中的前綴與差分(附源碼)

這篇具有很好參考價值的文章主要介紹了一文帶你深入了解算法筆記中的前綴與差分(附源碼)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一文帶你深入了解算法筆記中的前綴與差分(附源碼)

??作者介紹:22級樹莓人(計算機專業(yè)),熱愛編程<目前在c++階段,因為最近參加新星計劃算法賽道(白佬),所以加快了腳步,果然急迫感會增加動力>——目標Windows,MySQL,Qt,數(shù)據(jù)結(jié)構(gòu)與算法,Linux,多線程,會持續(xù)分享學習成果和小項目的
??作者主頁:熱愛編程的小K
??專欄鏈接:算法筆記

??歡迎各位→點贊?? + 收藏?? + 留言???
??總結(jié):希望你看完之后,能對你有所幫助,不足請指正!共同學習交流 ??

一文帶你深入了解算法筆記中的前綴與差分(附源碼)


??一、前綴和

?? A、一維前綴和
1、什么是一維前綴和

原數(shù)組: a[1], a[2], a[3], a[4], a[5], …, a[n]
前綴和 S[i]為數(shù)組的前 i項和
前綴和: S[i] = a[1] + a[2] + a[3] + … + a[i]

注意前綴和的下標一定要從 1開始, 避免進行下標的轉(zhuǎn)換,即定義S[0]等于0

2、一維前綴和的作用

快速求出元素組中某段區(qū)間的和

例如要求出l-r區(qū)間的和,則只需要執(zhí)行sum[r]-sum[l-1]

原理如下:

sum[r] = a[1] + a[2] + a[3] + a[l-1] + a[l] + a[l+1] ...... a[r]; sum[l - 1] = a[1] + a[2] + a[3] + a[l - 1]; sum[r] - sum[l - 1] = a[l] + a[l + 1]+......+ a[r];

并且時間復雜度為O(1)

3、習題:Acwing 795. 前綴和

輸入一個長度為 n的整數(shù)序列。

接下來再輸入 m個詢問,每個詢問輸入一對 l,r。

對于每個詢問,輸出原序列中從第 l個數(shù)到第 r個數(shù)的和

輸入格式

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

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

接下來 m 行,每行包含兩個整數(shù) l和 r,表示一個詢問的區(qū)間范圍。

輸出格式

共 m行,每行輸出一個詢問的結(jié)果。

數(shù)據(jù)范圍

1≤l≤r≤n
1≤n,m≤100000
?1000≤數(shù)列中元素的值≤1000

輸入樣例:
5 3
2 1 3 6 4
1 2
1 3
2 4
輸出樣例:
3
6
10
4、代碼詳解
#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N],sum[N];  //原數(shù)組與求和數(shù)組
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]+a[i];   //構(gòu)建前綴和
    }
    while(m--)
    {
        int L,R;
        cin>>L>>R;
        cout<<sum[R]-sum[L-1]<<endl;
    }
    return 0;
}
??B、二維前綴和(矩陣和)
1、二維前綴和推導

一文帶你深入了解算法筆記中的前綴與差分(附源碼)

從上圖我們很容易得到:圖1的面積=圖二的面積+圖三的面積+圖四的面積-圖五的面積(重復的面積)

所以我們得出二維前綴和的預處理公式:s[i][j]=s[i-1][j]+s[i][j-1]+a[i][j]-s[i-1][j-1]


接下來回歸問題去求以(x1,y1)為左上角和以(x2,y2)為右下角的矩陣的元素的和。

如圖:

一文帶你深入了解算法筆記中的前綴與差分(附源碼)

不難看出綠色的面積=s[x2][y2]+s[x2][y1-1]+s[x1-1][y2]-s[x1-1][y1-1]

且時間復雜度也為O(1)

2、習題:Acwing 796. 子矩陣的和

輸入一個 n行 m列的整數(shù)矩陣,再輸入 q個詢問,每個詢問包含四個整數(shù) x1,y1,x2,y2,表示一個子矩陣的左上角坐標和右下角坐標。對于每個詢問輸出子矩陣中所有數(shù)的和。

輸入格式

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

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

接下來 q行,每行包含四個整數(shù) x1,y1,x2,y2,表示一組詢問。

輸出格式

共 q 行,每行輸出一個詢問的結(jié)果。

數(shù)據(jù)范圍

1≤n,m≤1000
1≤q≤200000
1≤x1≤x2≤n
1≤y1≤y2≤m
?1000≤矩陣內(nèi)元素的值≤1000

輸入樣例:
3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4
輸出樣例:
17
27
21
3、代碼詳解
#include<iostream>
using namespace std;
const int N=1010;
int a[N][N],s[N][N];
int main()
{
    int n,m,q;
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
            //構(gòu)建前綴和
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]; 
        }
    while(q--)
    {
        int x1,y1,x2,y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        //求并輸出矩形前綴和
        cout<<s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]<<endl;
    }
    return 0;
    
}

??二、差分

??A、一維差分
1、什么是差分

類似于數(shù)學中的求導和積分,差分可以看成前綴和的逆運算。

這里舉一個例子:

先給一個原數(shù)組aa[1]、a[2]、a[3]、a[4]、a[5]...a[n]

然后這里再構(gòu)建一個數(shù)組b:b[1]、b[2]、b[3]...b[n]

使得:a[i]=b[1]+b[2]+b[3]...b[i]

即a是b的前綴和,反過來b就是a的差分

2、如何構(gòu)建差分數(shù)組

這里我們采取最暴力的做法,直接構(gòu)造,并且需要注意下標,所以我們這里還是令a[0]=0

注意:下面的構(gòu)造中,a為前綴和數(shù)組,b為差分數(shù)組

a[0]=0;
b[1]=a[1]-a[0];
b[2]=a[2]-a[1];
......
b[i]=a[i]-a[i-1];
3、差分數(shù)組有什么作用

我們先來看一個問題

給定區(qū)間[l ,r ],讓我們把a數(shù)組中的[ l, r]區(qū)間中的每一個數(shù)都加上c,即 a[l] + c , a[l+1] + c , a[l+2] + c ,,,,,, a[r] + c;

暴力做法是for循環(huán)l到r區(qū)間,時間復雜度O(n),如果我們需要對原數(shù)組執(zhí)行m次這樣的操作,時間復雜度就會變成O(n * m)。 這個時候就體現(xiàn)出差分的作用了,讓我們往下接著看

我們知道a是b的前綴和數(shù)組,所以改變b的一項就會改變a中有b的所有項

但是在有邊界之外的也多加上一個C,如圖所示

一文帶你深入了解算法筆記中的前綴與差分(附源碼)

所以這里我們需要執(zhí)行兩步操作

b[l]+=c;

b[r+1]-=c;

因此我們得出一維差分結(jié)論:給a數(shù)組中的[ l, r]區(qū)間中的每一個數(shù)都加上c,只需對差分數(shù)組b做 b[l] + = c, b[r+1] - = c。時間復雜度為O(1), 大大提高了效率。

4、練習 Acwing 797. 差分

輸入一個長度為 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ù)據(jù)范圍

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
5、代碼詳解

注意使用scanf進行輸入,效率比較高

#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N], b[N];
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        b[i] = a[i] - a[i - 1];      //構(gòu)建差分數(shù)組
    }
    int l, r, c;
    while (m--)
    {
        scanf("%d%d%d", &l, &r, &c);
        b[l] += c;       //將序列中[l, r]之間的每個數(shù)都加上c
        b[r + 1] -= c;
    }
    for (int i = 1; i <= n; i++)
    {
        a[i] = b[i] + a[i - 1];    //前綴和運算
        printf("%d ", a[i]);
    }
    return 0;
}
??B、二維差分(差分矩陣)

類似于前面的二維前綴和,這里引用大佬林小鹿的圖解

一文帶你深入了解算法筆記中的前綴與差分(附源碼)

所以要執(zhí)行四步操作:

b[x1][y1] += c;

b[x1][y2+1] -= c;

b[x2+1][y1] -= c;

b[x2+1][y2+1] += c;

3、習題:Acwing 798. 差分矩陣

輸入一個 n行 m列的整數(shù)矩陣,再輸入 q 個操作,每個操作包含五個整數(shù) x1,y1,x2,y2,c,其中 (x1,y1)和 (x2,y2) 表示一個子矩陣的左上角坐標和右下角坐標。每個操作都要將選中的子矩陣中的每個元素的值加上 c。請你將進行完所有操作后的矩陣輸出。

輸入格式

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

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

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

輸出格式

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

數(shù)據(jù)范圍

1≤n,m≤1000
1≤q≤100000,
1≤x1≤x2≤n
1≤y1≤y2≤m
?1000≤c≤1000
?1000≤矩陣內(nèi)元素的值≤1000文章來源地址http://www.zghlxwxcb.cn/news/detail-411368.html

輸入樣例:
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
4、代碼詳解
#include<iostream>
using namespace std;
const int N=1010;
int a[N][N],s[N][N];
int main()
{
    int n,m,q;
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&s[i][j]);
    //構(gòu)建差分矩陣
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            a[i][j]=s[i][j]-s[i][j-1]-s[i-1][j]+s[i-1][j-1]; 
    while(q--)
    {
        int x1,y1,x2,y2,c;
        scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&c);
        a[x1][y1]+=c;
        a[x1][y2+1]-=c;
        a[x2+1][y1]-=c;
        a[x2+1][y2+1]+=c;
    }
    //求和
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
           s[i][j] = a[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
    for (int i = 1; i <= n; i ++ )
    {
        for (int j = 1; j <= m; j ++ ) 
        printf("%d ", s[i][j]);
        cout << endl;
    }
    return 0;
}

到了這里,關(guān)于一文帶你深入了解算法筆記中的前綴與差分(附源碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【MySQL】一文帶你了解MySQL中的子查詢

    【MySQL】一文帶你了解MySQL中的子查詢

    子查詢指一個查詢語句嵌套在另一個查詢語句內(nèi)部的查詢,這個特性從MySQL 4.1開始引入 。 SQL 中子查詢的使用大大增強了 SELECT 查詢的能力 ,因為很多時候查詢需要從結(jié)果集中獲取數(shù)據(jù),或者需要從同一個表中先計算得出一個數(shù)據(jù)結(jié)果,然后與這個數(shù)據(jù)結(jié)果(可能是某個標量

    2024年02月08日
    瀏覽(27)
  • 一文帶你了解區(qū)塊鏈中15種共識算法

    一文帶你了解區(qū)塊鏈中15種共識算法

    區(qū)塊鏈技術(shù)席卷全球,提供了一種去中心化且安全的信息存儲和傳輸方式。它還徹底改變了交易的執(zhí)行方式,隨之而來的是廣泛的共識算法。在這里,共識算法在確保區(qū)塊鏈網(wǎng)絡(luò)的完整性方面發(fā)揮著關(guān)鍵作用。在本文中,我們將探討所有主要類型的區(qū)塊鏈共識算法、它們的含

    2024年02月01日
    瀏覽(28)
  • MAVEN利器:一文帶你了解MAVEN中的依賴管理

    MAVEN利器:一文帶你了解MAVEN中的依賴管理

    強大的構(gòu)建工具——Maven。作為Java生態(tài)系統(tǒng)中的重要組成部分,Maven為開發(fā)人員提供了一種簡單而高效的方式來構(gòu)建、管理和發(fā)布Java項目。無論是小型項目還是大型企業(yè)級應(yīng)用,Maven都能幫助開發(fā)人員輕松處理依賴管理、編譯、測試和部署等任務(wù)。 在上一篇文章中,我們學習

    2024年02月10日
    瀏覽(32)
  • [Maven-POM]你真的懂POM文件嗎? | 一文帶你深入了解POM.XML

    ?作者介紹:大二本科網(wǎng)絡(luò)工程專業(yè)在讀,持續(xù)學習Java,努力輸出優(yōu)質(zhì)文章 ?作者主頁:@逐夢蒼穹 ?所屬專欄:JavaEE ?如果覺得文章寫的不錯,歡迎點個關(guān)注一鍵三連??有寫的不好的地方也歡迎指正,一同進步?? 請查看我的這篇文章:[Java Web]Maven:一個管理和構(gòu)建Java項

    2024年02月07日
    瀏覽(22)
  • 【算法】一文帶你從淺至深入門dp動態(tài)規(guī)劃

    【算法】一文帶你從淺至深入門dp動態(tài)規(guī)劃

    本文要為大家?guī)淼氖莇p動態(tài)規(guī)劃,相信這是令很多同學頭疼的一個東西,也是在大廠面試中很喜歡考的一個經(jīng)典算法 ?? 本文總共會通過四道題來逐步從淺至深地帶讀者逐步認識dp動態(tài)規(guī)劃 首先在講解題目之前,我們要先來說說動態(tài)規(guī)劃理論基礎(chǔ),讓大家知道到底什么是【

    2024年02月07日
    瀏覽(25)
  • 一文讀懂flutter線程: 深入了解Flutter中的多線程編程

    一文讀懂flutter線程: 深入了解Flutter中的多線程編程

    在移動應(yīng)用開發(fā)領(lǐng)域,F(xiàn)lutter已經(jīng)成為了一個備受歡迎的框架,用于創(chuàng)建高性能、跨平臺的應(yīng)用程序。Flutter的一個關(guān)鍵特性是其能夠輕松處理多線程編程,以改進應(yīng)用程序的性能和響應(yīng)性。本文將深入探討Flutter中的多線程編程,包括為什么需要多線程、如何在Flutter中創(chuàng)建和管

    2024年01月20日
    瀏覽(25)
  • 算法基礎(chǔ)之差分和前綴和

    算法基礎(chǔ)之差分和前綴和

    結(jié)論:差分是前綴和的逆運算 舉例 一維差分 二維差分 用在一維子區(qū)間里的數(shù)都增減一個固定值,把對于區(qū)間內(nèi)每個數(shù)的操作轉(zhuǎn)換為對于差分數(shù)組中的端點的操作,時間復雜度降為o(1)。 用在二維子矩陣里的數(shù)都增減一個固定值,把對于子矩陣的每個數(shù)的操作轉(zhuǎn)換為對應(yīng)差分

    2024年02月07日
    瀏覽(23)
  • 前綴和&差分算法(Python版)

    前綴和與差分是常用的區(qū)間優(yōu)化方式,其中前綴和數(shù)組可以將區(qū)間查詢的時間復雜度降為常數(shù),而差分數(shù)組則可以將區(qū)間修改的時間復雜度降為常數(shù)。 前綴和知識點簡單易理解,但出題難度較大,需要根據(jù)題意挖掘出潛在的前綴和關(guān)系,建立輔助數(shù)組求解問題。 (1)一維前

    2024年04月17日
    瀏覽(46)
  • 【算法基礎(chǔ)】前綴和與差分

    【算法基礎(chǔ)】前綴和與差分

    ?? PREFACE ??歡迎各位→點贊 ?? + 收藏 ? + 評論 ?? ??系列專欄: 算法 ?? 種一棵樹最好是十年前其次是現(xiàn)在 前綴和指一個數(shù)組的某下標之前的所有數(shù)組元素的和(包含其自身)。前綴和分為一維前綴和,以及二維前綴和。前綴和是一種重要的預處理,能夠降低算法的時

    2024年01月19日
    瀏覽(19)
  • 【算法】—前綴和與差分詳解

    【算法】—前綴和與差分詳解

    ?前綴和指一個數(shù)組的某下標之前的所有數(shù)組元素的和( 即數(shù)列的前n項求和 ),前綴和是一種重要的 預處理 ,能夠降低算法的時間復雜度,可以快速地求出某一段的和,對于處理區(qū)間之間的問題是往往十分高效 相比較其他算法而言, 前綴和更像是一種解題的技巧,一種優(yōu)

    2024年02月04日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包