luogu 3373
線段樹懶標記維護乘與加
每個節點的sum,一定是這個點所帶的懶標記經過所有運算後最終的sum值,這種題目做起來一定要系統化,必須定好標準,決不能混亂。
每次詢問到乙個點,如果這個點不用深入下去,則直接打上標記即可,同時更新這個點的sum值,否則的話需要把標記傳給它的左右兒子,然後它的標記清0。一定要養成無論是修改還是詢問一旦進入子樹必須先push_down的好習慣,最後別忘了結束位置再根據它的左右節點sum值update一下。
乙個要注意的地方,由於有兩種標記,故也要定好兩種標記的優先順序。
乘法優於加法,即如果乙個地方打了乙個乘法標記,那麼它的乘法標記、加法標記、sum值都得乘這個標記值。如果打了乙個加法標記,則只需要修改這個點的加法標記與sum值,無須修改乘法標記,切勿優先標準混亂。
**如下:
#include
using
namespace std;
#define ll long long
const ll n=
110000
;ll n,m,p,op,x,y,k,mo;
struct nodet[n*4]
;void
update
(ll w)
void
down_push
(ll w,ll l,ll r)
void
build
(ll w,ll l,ll r)
ll mid=
(l+r)/2
;build
(w*2
,l,mid)
;build
(w*2+1
,mid+
1,r)
;update
(w);
}void
modifymul
(ll w,ll l,ll r,ll ll,ll rr,ll z)
down_push
(w,l,r)
; ll mid=
(l+r)/2
;if(ll<=mid)
modifymul
(w*2
,l,mid,ll,rr,z);if
(rr>mid)
modifymul
(w*2+1
,mid+
1,r,ll,rr,z)
;update
(w);
}void
modifyadd
(ll w,ll l,ll r,ll ll,ll rr,ll z)
down_push
(w,l,r)
; ll mid=
(l+r)/2
;if(ll<=mid)
modifyadd
(w*2
,l,mid,ll,rr,z);if
(rr>mid)
modifyadd
(w*2+1
,mid+
1,r,ll,rr,z)
;update
(w);
}ll query
(ll w,ll l,ll r,ll ll,ll rr)
intmain()
if(op==2)
if(op==3)
}return0;
}
luogu3373 模板 線段樹 2
題面 已知乙個數列,你需要進行下面三種操作 1.將某區間每乙個數乘上x 2.將某區間每乙個數加上x 3.求出某區間每乙個數的和 題解區間修改 區間查詢。維護兩個lazytag include include using namespace std const int maxn 100010 type...
luogu 3373 模板 線段樹2
如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數加上x 2.將某區間每乙個數乘上x 3.求出某區間每乙個數的和 輸入格式 第一行包含三個整數n m p,分別表示該數列數字的個數 操作的總個數和模數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包...
Luogu3373 模板 線段樹 2
不寫線段樹,就是要分塊!同樣需要打標記 在任何時候,a i mul times a i add bel i 表示 i 屬於哪一塊,a i 表示第 i 個位置的真實值 但是由於標記都是整塊整塊打上去的,無法單點修改,本來可能還可以利用逆元強行修改,問題是 p 571373 不是質數,那麼如何處理零散的...