首先肯定推薦學姐部落格!
炒雞優秀的學姐!
主要是貼**,並沒有什麼理論的講解。
例題:洛谷p3372[模板]線段樹1
洛谷p3373[模板]線段樹2
線段樹支援單點查詢、單點修改、區間查詢、區間修改等操作。
基本思想是二分
將線段樹節點用乙個結構體打包起來
建樹:
build(1, 1, n);
void build (int k, int ll, int
rr)
int mid = (tr[k].l + tr[k].r ) >> 1
; build (lson, ll, mid);
build (rson, mid + 1
, rr);
tr[k].v = tr[lson].v +tr[rson].v;
}
單點查詢:
void ask_point(intk) mid = (tr[k].l + tr[k].r) >> 1
;
if(x <= mid) ask_point(k << 1
);
else ask_point(k << 1 | 1
);}
單點修改:
void change_point(intk) mid = (tr[k].l + tr[k].r) >> 1
;
if(x <= mid) change_point(k << 1
);
else change_point(k << 1 | 1
); tr[k].w = tr[k << 1].w + tr[k << 1 | 1
].w;
}
區間查詢:
void ask_query (intk)
if(tr[k].f) down (k);
int m = (tr[k].l + tr[k].r) >> 1
;
if (z <=m) ask (lson);
if (y >m) ask (rson);
tr[k].v = tr[lson].v +tr[rson].v;
}
區間修改:
void change_query (intk)
if(tr[k].f) down (k);
int m = (tr[k].l + tr[k].r) >> 1
;
if (z <=m) c_v (lson);
if (y >m) c_v (rson);
tr[k].v = tr[lson].v +tr[rson].v;
}
lazy標記:
void down (intk)
感性理解
例一**:
#include #include//#define int long long
//#define long long int
#define lson k << 1
#define rson k << 1 | 1
using
namespace
std;
intn, m, z, y, w;
long
long
ans;
struct
node tr[
400001
];void build (int k, int ll, int
rr)
int mid = (tr[k].l + tr[k].r ) >> 1
; build (lson, ll, mid);
build (rson, mid + 1
, rr);
tr[k].v = tr[lson].v +tr[rson].v;
}void down (int
k) void c_v (int
k)
if(tr[k].f) down (k);
int m = (tr[k].l + tr[k].r) >> 1
;
if (z <=m) c_v (lson);
if (y >m) c_v (rson);
tr[k].v = tr[lson].v +tr[rson].v;
}void ask (int
k)
if(tr[k].f) down (k);
int m = (tr[k].l + tr[k].r) >> 1
;
if (z <=m) ask (lson);
if (y >m) ask (rson);
tr[k].v = tr[lson].v +tr[rson].v;
}int
main ()
else
if (x == 2
) }
return0;
}
例二**:
#include #includeusing
namespace
std;
struct
node tr[
400000
];long
long
a, b, ans, y, n, m, p;
intread ()
while (isdigit (ch))
return s *w;
}void build (int k, int ll, int
rr)
int m = (ll + rr) >> 1
; build (k
<< 1
, ll, m);
build (k
<< 1 | 1, m + 1
, rr);
tr[k].w = (tr[k << 1].w + tr[k << 1 | 1].w) %p;
return;}
void down (int
k) void mul_interval (int
k) down (k);
int m = (tr[k].l + tr[k].r) >> 1
;
if (a <= m) mul_interval (k << 1
);
if (b > m) mul_interval (k << 1 | 1
); tr[k].w = (tr[k << 1].w + tr[k << 1 | 1].w) %p;
return;}
void add_interval (int
k) down (k);
int m = (tr[k].r + tr[k].l) >> 1
;
if (a <= m) add_interval (k << 1
);
if (b > m) add_interval (k << 1 | 1
); tr[k].w = (tr[k << 1].w + tr[k << 1 | 1].w) %p;
return;}
void ask_interval (int
k) down (k);
int m = (tr[k].r + tr[k].l) >> 1
;
if (a <= m) ask_interval (k << 1
);
if (b > m) ask_interval (k << 1 | 1);}
intmain ()
else
if (nu == 2
)
else
if (nu == 3
) }
return0;
}
謝謝收看, 祝身體健康!
關於線段樹基礎
必須 二分法,樹的基礎 拓展 補碼,反碼,移碼,lowbit 了解什麼是線段樹及用途 線段樹,類模板題 just a hook include include include include include using namespace std const int t 100009 struct ...
題解 線段樹 關於時間
這是本蒟蒻的原創題 確實很簡單 本蒟蒻loj賬號diogenes 本題的難點在於每個操作會重複多次。核心思想是把第t秒的操作提前到第一秒,再減去多餘的部分。有一種構造方法 ad d i.j add i.j 表示區間 i j i,j 需要加的值。de l i.j del i.j 表示區間 i j i,...
關於吉利線段樹
這玩意兒又稱 segment tree beats 由吉老師 picks 美國隊長三位知名毒瘤發明。我的精神受到了汙染.線段樹什麼的太難了,不是很會啊.線段樹最強的地方在於,如果標記支援合併,那麼我們就能夠快速進行區間修改了。維護這樣乙個標記 a,b 表示 x to max x a b 顯然標記可合...