SCUEC 20 11 12字首差分之一通亂講

2021-10-10 11:43:40 字數 2783 閱讀 8161

在了解二維字首和之前,我們首先需要了解一下什麼是字首和。

如果我給你一串長度為n的數列a1,a2,a3…an,再給出m個詢問,每次詢問給出l,r兩個數,要求給出區間[l,r]裡的數的和,你會怎麼做,若是沒有了解過字首和的人看到這道題的想法可能是對於m次詢問,我每次都遍歷一遍它給的區間,計算出答案,這樣子的方法固然沒錯,但是其時間複雜度達到了o(n*m),如果資料量稍微大一點就有可能超時,而我們如果使用字首和的方法來做的話就能夠將時間複雜度降到o(n+m),大大節省了運算時間。至於怎麼用,請看下面一小段**

int a[maxn]

,f[maxn]

;for

(int i=

1;i<=n;i++

) f[i]

=f[i-1]

+a[i]

;

在這裡f陣列就是a陣列的字首陣列,它的本質就是對應的f[i]記載了對應前i個a[i]值的和,這樣我們在計算指定區間[l,r]的和時就可以簡單使用f[l]-f[r-1]來進行計算,大大降低了時間複雜度。

我們先來看一道簡單題

題目鏈結

洛谷cf18c stripe

我們直接上**

#include

using

namespace std;

int n,a[

100010

],s[

100010];

//s為記錄字首和的陣列

int ans=0;

//記錄答案

intmain()

//讀入+統計字首和

for(

int i=

1;i<=n-

1;i++

) cout<

//輸出答案

return0;

}

這道題就是一道典型的字首和的準模板題

接著我們再來看一道題也很簡單,但是模擬過程稍微有點複雜的題目

題目鏈結

我們還是先直接上**

#include

using

namespace std;

long

long n,k;

long

long a[

1000010];

long

long f[

1000010];

long

long ans=llong_max;

//記錄long long資料的最大值

long

long dis[

1000010];

intmain()

for(

int i=

1;i<=n;i++

)for

(int i=

1;i<=n;i++

) cout<

}

下面我們對這裡面的這條核心**進行一下解讀 dis[i]=f[i]+f[n]-f[i+k];

這樣搞應該還是比較清楚的吧

字首先說到這裡我們再來看差分

差分某種程度上來說是字首的逆運算,雖然我個人對這句話理解不深,但還是要裝著很懂的樣子把這句很權威的話說一遍(我好廢物啊,哈哈哈)

我們來了解一下什麼是差分。

給你一串長度為n的數列a1,a2,a3…an,要求對a[l]~a[r]進行m次操作:

操作一:將a[l]~a[r]內的元素都加上p

操作二:將a[l]~a[r]內的元素都減去p

最後再給出乙個詢問求a[l]-a[r]內的元素之和?

其實實現這個操作也很簡單,先來看一段簡單的**

//a[i]是最後每個數的對應值,add[i]是差分陣列

cin>>l>>r;

add[l]

++;add[r+1]

--;for(

int i=

1;i<=n;i++

) a[i]

=a[i-1]

+add[i]

;

我也忘了是我之前看到的還是我現在在敲這個時偶然之間想到的,下面給大家講解一種比較容易理解的思路

下面我們來看中石油的d題,好羨慕你們啊,有人這麼負責任地給你們講題,寫部落格,嗚嗚嗚,我嫉妒了

有了之前的鋪墊,我們還是直接上**吧

#include

using

namespace std;

typedef

long

long ll;

const

int max=

200002

;int n,m,s,t,a[max]

,add[max]

;int

num(

int a)

//判斷位數的函式,沒啥講的

return num;}}

intmain()

int sum=0;

for(

int i=

1;i<=n;i++

) cout<

}

好了就先水到這吧,溜了溜了。

字首和 差分

數列的字首和 sum i 表示a 1 a i 的和 用處1 求i j的和sum j sum i 1 用處2 區間修改。設定乙個change陣列。當區間 i,j 上要加k時,我們令change i k,令change j 1 k。如果我們對change陣列求字首和的話,字首和sum change i ...

字首和 差分

有n個數和q次操作,每一次操作指明了要操作的區間 l,r 以及讓該區間內的所有元素全部加c 輸出q次操作後所有元素的大小 第一行 n q 1 n,q 2 105 第二行 n個數 a1,a2 an 106 ai 106 接下來q 行 每行3個數 l r c 表示 l,r 區間內每個數加c 1 l r ...

字首和 差分

顧名思義 用某乙個陣列來記錄陣列a前i項和,這個還可以用來求區間 l,r 的和 s r s l 1 因為第l項也在區間內 話不多說,直接上例題 leetcode 5393 ac const int maxn 1e5 5 class solution int ans 0 for int i 0 i k...