字首和 差分 樹狀陣列 線段樹

2021-10-09 22:47:03 字數 2401 閱讀 6122

字首和

應用:區間查詢,不涉及數的變化。求區間[l,r]d的和

一維字首和:

s[i] = a[1] + a[2] + … + a[i];

s[i] = s[i-1] + a[i];

二維字首和:

s[i][j] = 第 i 行第 j 列格仔左上部分所有元素的和

以(x1,y1)為左上角,(x2,y2)為右下角

s[x2,y2] - s[x2, y1-1] - s[x1-1, y2] + s[x1-1,y1-1]

差分

應用:字首和的逆運算,給區間[l,r]中每個數加上c

一維差分:

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

二維差分:

以(x1,y1)為左上角,(x2,y2)為右下角的子矩陣中所有元素加上c

s[x1,y1] += c, s[x1, y2+1] -= c, s[x2+1,y1] -=c, s[x2+1,y2+1] += c

樹狀陣列:

應用:樹狀陣列作為線段樹中的一部分,可以進行單點修改和區間查詢。時間複雜度為o(logn)

樹狀陣列、線段樹裸題

給定 n 個數組成的乙個數列,規定有兩種操作,一是修改某個元素,二是求子數列 [a,b] 的連續和。

輸入格式 第一行包含兩個整數 n 和 m,分別表示數的個數和操作次數。

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

接下來 m 行,每行包含三個整數 k,a,b (k=0,表示求子數列[a,b]的和;k=1,表示第 a 個數加 b)。

數列從 1 開始計數。

輸出格式 輸出若干行數字,表示 k=0 時,對應的子數列 [a,b] 的連續和。

注意點:

1.有三個核心函式。lowbit(int n) 返回數字n的最後一位1

2. query(int x) tr[x]表示的是(x-2^k, x]的和

#include

#include

#include

#include

using

namespace std;

const

int n =

100010

;int n, m;

int a[n]

;int tr[n]

;int

lowbit

(int x)

intquery

(int x)

void

modify

(int a,

int b)

intmain()

return0;

}

線段樹應用:應用範圍廣。染色、面積等等(還沒有學習到)。懶標記(只知道這個名詞)

注意點:

1.資料範圍4*n

2.很容易出錯

樹狀陣列和線段樹

主要解決兩個問題 其他問題可以轉化 更新某一點的值 求區間值 時間按複雜度 logn 原陣列a 1 a 2 a n 寫成樹狀陣列c c x x lowbit x x 左開右閉 筆記 主要 const int n int tr n int lowbit int x void add int x,int...

線段樹和樹狀陣列

引入1 有n個數 n 50000 個數,m m 50000 次詢問。每次詢問區間l到r的數的和。要求輸出每一次詢問的結果.分析 1.用字首和問題進行求解 再開乙個陣列 暫且記為b n 設n個數所組成的陣列為a n b i 用來記錄從a 1 到a i 的所有數字的和 即 b 1 a 1 b 2 b 1...

線段樹和樹狀陣列

線段樹 segment tree 和樹狀陣列是兩種常用的資料結構。他們用來維護乙個區間內的操作,可以在 logn 的複雜度上進行查詢和修改。線段樹可以維護對乙個區間的查詢和修改,可以對區間進行分塊查詢,而樹狀陣列是線段樹的閹割版,經常用來區間查詢,但修改只能進行單點修改,經過改造之後可以區間修改,區...