每日四題打卡 3 18 字首矩陣和 查分

2021-10-04 02:09:06 字數 4739 閱讀 9239

1、字首和

輸入乙個長度為n的整數序列。

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

對於每個詢問,輸出原序列中從第l個數到第r個數的和。

輸入格式

第一行包含兩個整數n和m。

第二行包含n個整數,表示整數數列。

接下來m行,每行包含兩個整數l和r,表示乙個詢問的區間範圍。

輸出格式

共m行,每行輸出乙個詢問的結果。

資料範圍

1≤l≤r≤n1≤l≤r≤n,

1≤n,m≤1000001≤n,m≤100000,

−1000≤數列中元素的值≤1000−1000≤數列中元素的值≤1000

輸入樣例:

5 3

2 1 3 6 4

1 21 3

2 4

輸出樣例:

3

610

//步驟: 定義s存每個位置的字首和s[i] = s[i - 1] + a[i],l-r區間和:s[r] - s[l - 1]

#include using namespace std;

const int n = 100010;

int a[n], s[n];//少了這個s[n]: si = a1 + a2 + ...+ ai,

int main()

}

2、子矩陣和

輸入乙個n行m列的整數矩陣,再輸入q個詢問,每個詢問包含四個整數x1, y1, x2, y2,表示乙個子矩陣的左上角座標和右下角座標。

對於每個詢問輸出子矩陣中所有數的和。

輸入格式

第一行包含三個整數n,m,q。

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

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

輸出格式

共q行,每行輸出乙個詢問的結果。

資料範圍

1≤n,m≤10001≤n,m≤1000,

1≤q≤2000001≤q≤200000,

1≤x1≤x2≤n1≤x1≤x2≤n,

1≤y1≤y2≤m1≤y1≤y2≤m,

−1000≤矩陣內元素的值≤1000−1000≤矩陣內元素的值≤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

2721

//步驟:初始化字首和:按照公式來:s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];

//求輸出子矩陣中所有數的和:s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1]

#include using namespace std;

const int n = 1010;

int a[n][n], s[n][n];

int main()

return 0;

}

3、差分

輸入乙個長度為n的整數序列。

接下來輸入m個操作,每個操作包含三個整數l, r, c,表示將序列中[l, r]之間的每個數加上c。

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

輸入格式

第一行包含兩個整數n和m。

第二行包含n個整數,表示整數序列。

接下來m行,每行包含三個整數l,r,c,表示乙個操作。

輸出格式

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

資料範圍

1≤n,m≤1000001≤n,m≤100000,

1≤l≤r≤n1≤l≤r≤n,

−1000≤c≤1000−1000≤c≤1000,

−1000≤整數序列中元素的值≤1000−1000≤整數序列中元素的值≤1000

輸入樣例:

6 3

1 2 2 1 2 1

1 3 1

3 5 1

1 6 1

輸出樣例:

3 4 5 3 4 2
//步驟:還是不熟練,晚上繼續寫一遍

//所有陣列進行插入操作:b[l] += c;b[r + 1] -= c;insert(i, i, a[i]),插入乙個數c,求原來陣列字首和:b[i] += b[i - 1];,輸出b[i]

/*概念助於理解

假設給定原陣列是 a1, a2, a3,..., an.

構造b陣列 b1,b2,...,bn.使得 ai = b1 + b2 + ... + bi;

則有 b1 = a1;

b2 = a2 - a1;

b3 = a3 - a2;

...an = an - an-1;

b則稱為a的差分,a則是b的字首和。字首和和差分是逆運算。

在a陣列裡面[l,r]區間加上乙個固定值c,即 al + c , al+1 + c ,...,ar + c;

對a陣列[l,r]區間加上c,又因為ai = b陣列得字首和,所以對b差分陣列來說同樣的也要加上c-->bl + c-->al

也會自動加上c-->al ... an都會加上c。但是加c只要執行到r,所以第r+1就要減去c,這樣就可以抵消r之後加上的c。

*/#include using namespace std;

const int n = 100010;

int a[n], b[n];

void insert(int l, int r, int c)

int main()

//求原來陣列的值,對差分陣列求字首和

for (int i = 1; i <= n; i ++) b[i] += b[i - 1];// 這裡是b[i] += b[i - 1];不是b[i] = b[i - 1]+ a[i];

for (int i = 1; i <= n; i ++) cout << b[i] << ' ';

return 0;

}

4、差分矩陣

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

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

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

輸入格式

第一行包含整數n,m,q。

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

接下來q行,每行包含5個整數x1, y1, x2, y2, c,表示乙個操作。

輸出格式

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

資料範圍

1≤n,m≤10001≤n,m≤1000,

1≤q≤1000001≤q≤100000,

1≤x1≤x2≤n1≤x1≤x2≤n,

1≤y1≤y2≤m1≤y1≤y2≤m,

−1000≤c≤1000−1000≤c≤1000,

−1000≤矩陣內元素的值≤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

//步驟跟差分一樣的,不過多了一維,然後insert變了

/*1、insert:當bx1 y1加上c的時候,由於b是a的字首和,則會將點(x1, y1)左和下的元素加上c。所以我們要減去出去劃線之外的多餘的區域,所以需要減去 b(x2+1, y1) 和 b(x1, y2+1)。上圖所示但是減去兩者將會減兩次b(x2+1, y1) 和 b(x1, y2+1)重疊的區域,所以要將b(x2 +1,y2 + 1) 加回來.得到公式如下:

b(x1, y1) += c;

b(x2 + 1, y1) -= c;

b(x1, y2 + 1) -= c;

b(x2 + 1, y2 + 1) += c;

2、 求原來陣列的值,對差分陣列求字首和:b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];

*/#include using namespace std;

const int n = 1010;

int n, m, q;

int a[n][n], b[n][n];

void insert(int x1, int y1, int x2, int y2, int c)

int main()

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 ++)

return 0;

}

牛客 每日一題 Xorto 題解(異或 字首和)

選取任意不重疊的兩個區間,使異或結果為0 前言已經想到了用字首和優化就是不知道該怎麼判斷他們不是重疊 正文暴力是列舉兩個區間左右端點,但是顯而易見會tle,我們可以考慮只列舉其中乙個區間 x,y 這個區間的異或和可以很容易的在o 1 時間複雜度通過字首異或和求得。如果我們規定 x,y 是右邊的那個區...

每日一題之 面試題 幸運巧克力(字首和 hash)

題目描述 思路 注意到每個元素都是 x 0,所以該陣列的字首和是遞增的。要找到連續的子串行之和等於k 即找到 sum i sum j k 且 0 j i 兩重for迴圈會超時,注意到字首和是遞增的,那麼將上式改寫成 sum i k sum j 這時候只要將字首和對映成下標,這樣只需要一重for迴圈,...

寒假刷題打卡第十九天 陣列和矩陣

錯誤的集合 最開始的想法是排序。但是 class solution int lose 1 int repeat 1 for int i 0 isize i return 尋找重複數 思路一 異或運算。先從1異或到n,將得到的值與陣列中的每個值異或運算。結果不對,因為,陣列中並非每個數都會出現一遍。思...