複習 線段樹基礎

2022-09-19 06:42:12 字數 1322 閱讀 9820

大部分題目是純模板,只寫一下《山海經》

題意:查詢區間最大欄位和(不帶修)

考慮區間最大子段和由**貢獻得到,

可能是lson的ans,rson的ans,也可以是lson與rson拼接而成

只需要抽象出加法(push_up)操作,就很好理解了

網上題解太麻煩, 需要各種分類討論,容易寫掛

所以直接抽象出加法即可

維護4個range:左側最大和lm、右側最大和rm、總和sum、最大子段和ans

\(ans = max(lm+rm, l.ans, r.ans)\)

然後套路維護剩下的\(lm rm sum\)即可

需要注意的幾個地方:區間為空時候要特判一下即可

即:區間為空的時候區間加法的l,r會掛掉,然後區間加之前需要判斷是否為空區間

#include#include#include#includeconst int n = 1e5+10, tr = 4*n;

int a[n];

int n, q;

struct rg_t

rg_t(int val_, int l_, int r_):val(val_), l(l_), r(r_){}

friend bool operator <(const rg_t& x, const rg_t& y)

bool empty()const

void make_empty()

friend rg_t operator +(const rg_t& x, const rg_t& y)

};struct segment_tree

node(int val, int u)

node(rg_t ans_, rg_t lm_, rg_t rm_, rg_t sum_):ans(ans_), lm(lm_), rm(rm_),sum(sum_) {}

bool empty()

friend node operator +(const node& a, const node& b)

}tree[tr];

void update(int rt, int val, int l)

void push_up(int rt)

void build(int rt, int l, int r)

node query(int rt, int l, int r, int s, int t)

}segt;

int main()

segt.build(1 ,1, n);

for(int i = 1; i <= q; ++i)

return 0;

}

線段樹複習

p2572 scoi2010 序列操作 這道題題解已經很多了 但是我還是想寫一篇 紀念 調三天 思路 很簡單 struct node tree maxn 2 len 長度 sum 1的個數 lazy 把 a,b 區間內的所有數全變成0 1標記 rev 反轉標記 lsum 1 0 記錄從左邊開始的最長...

RMQ 線段樹複習

首先是rmq include include includeusing namespace std const int maxn 50000 100 int dmax maxn 20 int dmin maxn 20 void initmax int n,int d 初始化最大值查詢 遞迴建立線段樹...

線段樹 01 線段樹基礎

物理上 public class segmenttree public int getsize public e get int index 返回完全二叉樹的陣列表示中,乙個索引所表示的元素的左孩子節點的索引 private int leftchild int index 返回完全二叉樹的陣列表示中...