模板
以區間和為例。
ll ls(ll p)ll rs(ll p)
void
push_up(ll p)
void
build(ll p,ll l,ll r)
ll mid=(l+r)>>1
; build(ls(p),l,mid);
build(rs(p),mid+1
,r);
push_up(p);
}void
f(ll p,ll l,ll r,ll k)
void
push_down(ll p,ll l,ll r)
void
update(ll nl,ll nr,ll p,ll l,ll r,ll k)
push_down(p,l,r);
ll mid=(l+r)>>1
;
if(nl<=mid) update(nl,nr,ls(p),l,mid,k);
if(nr>mid) update(nl,nr,rs(p),mid+1
,r,k);
push_up(p);
}ll query(ll ql,ll qr,ll p,ll l,ll r)
例題題面
分析
因為數列中的數$\le 10^$,所以最多開方$6$次就可變為$1$。
當乙個數已經等於$0$或$1$時,再開方就沒有意義了(值不變)。
因此當線段樹中某個葉子節點的值為$0$或$1$時,就給它打標記,可以不再操作。
同樣,某個父親節點的兩個子節點都被標記時,也給它打標記。
詳情見**
1 #include2#define ll long long
3using
namespace
std;
4const
int n=1e5+5;5
intn,m;
6 ll a[n],sum[n<<2];7
bool tag[n<<2];8
inline ll read()
1415 inline int ls(int p)
16 inline int rs(int p)
17void push_up(int
p) 21
void build(int p,int l,int
r) 23
int mid=(l+r)>>1;24
build(ls(p),l,mid);
25 build(rs(p),mid+1
,r);
26push_up(p);27}
28void update(int nl,int nr,int p,int l,int
r) 35
int mid=(l+r)>>1;36
if(nl<=mid) update(nl,nr,ls(p),l,mid);
37if(mid1
,r);
38push_up(p); 39}
40 ll query(int ql,int qr,int p,int l,int
r) 48
49int
main()
60 }
例題 線段樹
1 注意討論不能建樹的情況 nkoj 1321 數列操作問題 時間限制 10000 ms 空間限制 165536 kb 問題描述 假設有一列數 1 i n 支援如下兩種操作 將ak的值加d。k,d是輸入的數 輸出as as 1 at。s,t都是輸入的數,s t 輸入格式 第一行乙個整數n,第二行為n...
線段樹例題
線段樹可以說是每次比賽中必出的題了,但是線段樹好難,我太難了,我上輩子一定是一道線段樹的題。下面是一些基礎線段樹的題目,入門必備。線段樹是一種二叉搜尋樹,將原始資料都存在葉節點,依次表示出每個葉節點的根節點。一般陣列開到葉節點數量的4倍。關於線段樹的例題 hdu1166 敵兵布陣 按照指示來就可以 ...
例題 線段樹 lazy
1 1 lazy思想 對整個結點進行的操作,先在結點上做標記,而並非真正執行,直到根據查詢操作的需要分到下層。2 延遲標記 lazy 如果需要對乙個區間中每乙個葉結點進行操作,我們不妨先別忙著操作,而是在所有大區間上做乙個標記,下一次遇到或要用到時,再進行處理 標記傳遞 達到減少操作次數,提高線段樹...