線段樹基本操作(1)

2021-07-31 23:30:24 字數 1170 閱讀 1542

(建樹,查詢和單點修改)把一段長度為2^k的區間逐次對半分,可以總共分成2^(k+1)-1各節點,變成了一棵二叉樹

對於區間[lt, rt],它的子節點為區間[lt, mid]和區間[mid+1, rt]

查詢時只要要查詢的區間的左右邊界剛好等於已知區間的邊界,就可以返回值了,不需要一搜到底

對於單點修改,基本上和二分查詢差不多(查詢時查詢的值是該點的下標)

//線段樹 

#include

#include

#include

#include

using namespace std;

const int maxn = 10000 + 10;

int n;

int val[2

*maxn], p[maxn];

void build(int node, int

lt, int rt) //建樹

int mid = (lt + rt) >> 1;

build(node*2, lt, mid); build(node*2+1, mid+1, rt);

val[node] = min(val[node*2], val[node*2+1]);

return ;

}int query(int node, int

lt, int rt, int ll, int rr) //區間查詢

//lt, rt:點node的左右區間 ll, rr:要查的左右區間

// 使用條件:相鄰的區間的資訊可以被合併成兩個區間的並區間的資訊

void change(int node, int

lt, int rt, int u, int add) //單點修改

//u要修改的值的下標,add要給修改的值加上的值

int mid = (lt + rt) >> 1;

if(u <= mid) change(node*2, lt, mid, u, add);

if(u > mid) change(node*2+1, mid+1, rt, u, add);

val[node] = min(val[node*2], val[node*2+1]); //回溯修改

} int main()

線段樹基本操作(2)

假如指定乙個操作給一段區間的所有值加2,求任意區間的最小值 更新 才發現在change是就更改結點值而查詢時只釋放結點會更快,下面摘自網上 對於任意區間的修改,我們先按照查詢的方式將其劃分成線段樹中的結點,然後修改這些結點的資訊,並給這些結點標上代表這種修改操作的標記。在修改和查詢的時候,如果我們到...

線段樹的基本操作

點更新 1 include 點更新2 include 3 include 4 5using namespace std 67 const int n 10000 8 intn,m,a n 9struct node 10tree 4 n 1415 void build int id,int l,int...

線段樹及其基本操作

處理何種問題 陣列單點更新,單點查詢,區間更新,區間求和,區間求最值。效能 時間複雜度為o logn 原理 區間跟新的懶惰標記了解一下,其餘略 實現步驟 略 線段樹的區間求最值差別不大,在此貼乙份a過題的最值 用來對比找bug。include include include includeusing...