為了能讓朋友們更好的理解演算法我分了倆塊:
樹狀陣列
目錄
時間複雜度以及適用範圍
線段數其實就是個二叉樹。
線段數的儲存
線段數的函式
建立線段數
求區間和
求區間最大值
修改區間中某個元素的值
舉個例子
線段數比樹狀陣列時間複雜度要大,但是應用更廣泛,一般用於複雜的區間求和和求最大值,比如求取最大值為題就不能用樹狀陣列,要用線段數。
用結構體儲存每個線段數節點的邊界以及想求的值,假設區間的長度為n,需要的線段數節點的個數至少為4*n
這是求區間和的問題:
void pushup(int u)
void build(int u,int x,int y);
return ;
} tr[u]=;
int mid=x+y>>1;
build(u<<1,x,mid);
build(u<<1|1,mid+1,y);
pushup(u);
}
這是求區間最大值的問題:
void pushup(int u)
void build(int u,int l,int r);
} else;
int mid=l+r>>1;
build(u<<1,l,mid);build(u<<1|1,mid+1,r);
pushup(u);
}}
int query(int u,int l,int r)
int query(int u,int x,int y)
void modify(int u,int a,int b)
int mid =tr[u].l+tr[u].r >> 1;
if(a<=mid ) modify(u<<1,a,b);
else modify(u<<1|1,a,b);
pushup(u);
}
1270. 數列區間最大值
輸入一串數字,給你 mm 個詢問,每次詢問就給你兩個數字 x,yx,y,要求你說出 xx 到 yy 這段區間內的最大數。
輸入格式
第一行兩個整數 n,mn,m 表示數字的個數和要詢問的次數;
接下來一行為 nn 個數;
接下來 mm 行,每行都有兩個整數 x,yx,y。
輸出格式
輸出共 mm 行,每行輸出乙個數。
資料範圍
1≤n≤1051≤n≤105,
1≤m≤1061≤m≤106,
1≤x≤y≤n1≤x≤y≤n,
數列中的數字均不超過231−1231−1
輸入樣例:
10 2
3 2 4 5 6 8 1 2 9 7
1 43 8
輸出樣例:
5
8
code:
#include#include#include#includeusing namespace std;
const int maxn=1e5+10;
int w[maxn];
int n,m;
struct nodetr[maxn*4];
void pushup(int u)
void build(int u,int l,int r);
} else;
int mid=l+r>>1;
build(u<<1,l,mid);build(u<<1|1,mid+1,r);
pushup(u); }}
int query(int u,int x,int y)
int main()
build(1,1,n);
int x,y;
while(m--)
return 0;
}
線段樹與樹狀陣列的綜合運用
前言 線段樹樹狀陣列是高階資料結構最基本的部分,資料結構又是省選最基本的部分,所以從他開始整理一下。題目以洛谷和bz為基底 1.基礎運用 資料結構最基本的問題就是操作和詢問的問題,修改可以分為點修改 包括點的函式運算 區間運算 區間最大最小和取模 區間set 其中點修改就是領出樹上的一條長鏈,對其末...
樹狀陣列 詳解
對於普通陣列,其修改的時間複雜度位o 1 而求陣列中某一段的數值和的時間複雜度為o n 因此對於n的值過大的情況,普通陣列的時間複雜度我們是接受不了的。在此,我們引入了樹狀陣列的資料結構,它能在o logn 內對陣列的值進行修改和查詢某一段數值的和。假設a陣列為儲存原來的值得陣列,c為樹狀陣列。我們...
樹狀陣列詳解
樹狀陣列求區間和的一些常見模型 樹狀陣列在區間求和問題上有大用,其三種複雜度都比線段樹要低很多 有關區間求和的問題主要有以下三個模型 以下設a 1.n 為乙個長為n的序列,初始值為全0 1 改點求段 型,即對於序列a有以下操作 修改操作 將a x 的值加上c 求和操作 求此時a l.r 的和。這是最...