poj 3468 線段樹 lazy思想

2021-06-22 05:41:43 字數 1646 閱讀 3603

思路:如果直接去做,每次都更新到葉子節點,那必然會tle,我們可以採用lazy的思想:沒必要每次更新都更新到葉子節點,只要有乙個合適的範圍就用乙個增量來記錄它,當下一次詢問時,如果這個範圍正好合適詢問的範圍,就直接是這個節點的sum值加上這個區間長度*lnc,再加到總和上去,若這個節點的範圍不適合所要查詢的範圍,那麼就要查詢它的子節點,這個時候再把增量傳給她的子節點,並且清空父親節點的增量,這樣效率能大大提高。

1 #include2 #include3 #include4 #include5

using

namespace

std;

6#define maxn 100010

7 typedef long

long

ll;8

9struct

nodenode[maxn<<2

];14

15int

n,q;

1617

void build(int l,int r,int

rt)18

23 node[rt].lnc=node[rt].sum=0;24

int m=(l+r)>>1

;25 build(l,m,rt<<1

);26 build(m+1,r,(rt<<1)|1

);27}28

29void updata(int l,int r,int rt,int

id,ll x)

3035 node[rt].sum+=x;

36int m=(l+r)>>1;37

if(id<=m)else

40 updata(m+1,r,(rt<<1)|1

,id,x);41}

4243

void add_updata(int l,int r,int rt,int l,int

r,ll x)

44else

if(l<=l&&r<=r)else

if(l>=l&&r>=r)else

if(l<=l&&r<=r)

55int m=(l+r)>>1;56

if(r<=m)else

if(l>m)else64}

6566

ll sum;

67void query(int l,int r,int rt,int l,int

r)68

73//

若上面if條件不成立,則要詢問它的子節點,此時增量要下傳,並且要更新其本身的sum;

74 node[rt<<1].lnc+=node[rt].lnc;

75 node[(rt<<1)|1].lnc+=node[rt].lnc;

76 node[rt].sum+=node[rt].lnc*(r-l+1

);77 node[rt].lnc=0;78

int m=(l+r)>>1;79

if(r<=m)else

if(l>m)else87}

8889

intmain()

9099

while(q--)else

110}

111return0;

112}

113114

115

view code

poj 3468 線段樹lazy操作

題意 區間每個數加上乙個數,詢問乙個區間之和.include include include include include include include include include define ll long long define ls rt 1 define rs rt 1 1 def...

poj 3468 線段樹 lazy思想

思路 如果直接去做,每次都更新到葉子節點,那必然會tle,我們可以採用lazy的思想 沒必要每次更新都更新到葉子節點,只要有乙個合適的範圍就用乙個增量來記錄它,當下一次詢問時,如果這個範圍正好合適詢問的範圍,就直接是這個節點的sum值加上這個區間長度 lnc,再加到總和上去,若這個節點的範圍不適合所...

poj 3468 線段樹區間更新 lazy思想

題目大意 題目挺好理解的,就是給你一串數字,然後會在某一區間上,使區間的所有數字都加上乙個數,也就是更新這段區間的數字,最後再進行對某一區間的求值操作。題目分析 因為這道題目和我之前剛剛做的那道題目很類似,都是區間段更新的題目,但是有所不同的是,那個題目是直接賦值更新,而這個題目是區間進行加和,不是...