思路:如果直接去做,每次都更新到葉子節點,那必然會tle,我們可以採用lazy的思想:沒必要每次更新都更新到葉子節點,只要有乙個合適的範圍就用乙個增量來記錄它,當下一次詢問時,如果這個範圍正好合適詢問的範圍,就直接是這個節點的sum值加上這個區間長度*lnc,再加到總和上去,若這個節點的範圍不適合所要查詢的範圍,那麼就要查詢它的子節點,這個時候再把增量傳給她的子節點,並且清空父親節點的增量,這樣效率能大大提高。
1 #include2 #include3 #include4 #include5view codeusing
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
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思想
題目大意 題目挺好理解的,就是給你一串數字,然後會在某一區間上,使區間的所有數字都加上乙個數,也就是更新這段區間的數字,最後再進行對某一區間的求值操作。題目分析 因為這道題目和我之前剛剛做的那道題目很類似,都是區間段更新的題目,但是有所不同的是,那個題目是直接賦值更新,而這個題目是區間進行加和,不是...