假如指定乙個操作給一段區間的所有值加2,求任意區間的最小值
更新:才發現在change是就更改結點值而查詢時只釋放結點會更快,下面摘自網上
對於任意區間的修改,我們先按照查詢的方式將其劃分成線段樹中的結點,然後修改這些結點的資訊,並給這些結點標上代表這種修改操作的標記。在修改和查詢的時候,如果我們到了乙個結點p,並且決定考慮其子結點,那麼我們就要看看結點p有沒有標記,如果有,就要按照標記修改其子結點的資訊,並且給子結點都標上相同的標記,同時消掉p的標記。下面是**
//線段樹區間修改
#include
#include
#include
#include
using namespace std;
const int maxn = 10000 + 10;
int n;
int val[2
*maxn], p[maxn];
int sign[2
*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 ;
}void change(int node, int
lt, int rt, int ll, int rr) //區間修改
int mid = (lt + rt) >> 1;
if(rr <= mid)
if(ll > mid)
change(node*2, lt, mid, ll, mid);
change(node*2+1, mid+1, rt, mid+1, rr);
}int query(int node, int
lt, int rt, int ll, int rr) //區間查詢
if(lt == rt) return val[node];
int mid = (lt + rt) >> 1;
if(rr <= mid) return query(node*2, lt, mid, ll, rr);
if(ll > mid) return query(node*2+1, mid+1, rt, ll, rr);
int v1 = query(node*2, lt, mid, ll, mid);
int v2 = query(node*2+1, mid+1, rt, mid+1, rr);
return val[node] = min(v1, v2);
} int main()
線段樹基本操作(1)
建樹,查詢和單點修改 把一段長度為2 k的區間逐次對半分,可以總共分成2 k 1 1各節點,變成了一棵二叉樹 對於區間 lt,rt 它的子節點為區間 lt,mid 和區間 mid 1,rt 查詢時只要要查詢的區間的左右邊界剛好等於已知區間的邊界,就可以返回值了,不需要一搜到底 對於單點修改,基本上和...
線段樹的基本操作
點更新 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...