字首和
應用:區間查詢,不涉及數的變化。求區間[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 的複雜度上進行查詢和修改。線段樹可以維護對乙個區間的查詢和修改,可以對區間進行分塊查詢,而樹狀陣列是線段樹的閹割版,經常用來區間查詢,但修改只能進行單點修改,經過改造之後可以區間修改,區...