如題,已知乙個數列,你需要進行下面三種操作:
1.將某區間每乙個數乘上x
2.將某區間每乙個數加上x
3.求出某區間每乙個數的和
第一行包含三個整數n、m、p,分別表示該數列數字的個數、操作的總個數和模數。
第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。
接下來m行每行包含3或4個整數,表示乙個操作,具體如下:
操作1: 格式:1 x y k 含義:將區間[x,y]內每個數乘上k
操作2: 格式:2 x y k 含義:將區間[x,y]內每個數加上k
操作3: 格式:3 x y 含義:輸出區間[x,y]內每個數的和對p取模所得的結果
時空限制:1000ms,128m
資料規模:
對於30%的資料:n<=8,m<=10
對於70%的資料:n<=1000,m<=10000
對於100%的資料:n<=100000,m<=100000
(資料已經過加強_)
輸出包含若干行整數,即為所有操作3的結果。
5 5 38
1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4172
樣例說明:
題目顯然是用線段樹來做,具體難點為如何同時實現加法與乘法
加點和乘法可以分別用乙個 laz
ylazy
lazy
惰性標記進行傳遞
這裡傳遞時有優先順序問題,若乙個節點同時有加標記和乘標記應該是乘法優先
例如一節點值為 a
aa ,其需要 +b+b
+b、 ×
c\times c
×c,應該首先把 a、b
a、ba、
b 乘上 c
cc 得到 acac
ac和 +bc
+bc+b
c ,之後再進行 +
++ 操作得到 ac+
bcac+bc
ac+b
c
#include
using
namespace std;
int mod;
class
seg_tree};
int n;
vector tree;
node unite
(const node &k1,
const node &k2)
void
pull
(int o)
void
push
(int o,
int l,
int r)
if(tree[o]
.add !=0)
}void
build
(int o,
int l,
int r,
const vector
&v)int m =
(l + r)
>>1;
build
(o <<
1, l, m, v)
;build
(o <<1|
1, m +
1, r, v)
;pull
(o);
}seg_tree
(const vector
&v)void
modifyadd
(int o,
int l,
int r,
int ll,
int rr, type_t v)
push
(o, l, r)
;int m =
(l + r)
>>1;
if(ll <= m)
modifyadd
(o <<
1, l, m, ll, rr, v);if
(rr > m)
modifyadd
(o <<1|
1, m +
1, r, ll, rr, v)
;pull
(o);
}void
modifyadd
(int ll,
int rr, type_t v)
void
modifymul
(int o,
int l,
int r,
int ll,
int rr, type_t v)
push
(o, l, r)
;int m =
(l + r)
>>1;
if(ll <= m)
modifymul
(o <<
1, l, m, ll, rr, v);if
(rr > m)
modifymul
(o <<1|
1, m +
1, r, ll, rr, v)
;pull
(o);
}void
modifymul
(int ll,
int rr, type_t v)
node query
(int o,
int l,
int r,
int ll,
int rr)
node query
(int ll,
int rr)};
intmain()
else
if(op ==2)
else
}return0;
}
洛谷P3373 模板 線段樹2
這題有毒啊,敲了我一晚上加一早上,總算a了。由於有加和乘兩個操作,要用2個lazy陣列。核心難點就是2個lazy陣列會相互影響。因為乘影響加,加不影響乘,所以我們先算乘。include include include include include include include include i...
線段樹(洛谷P3373模板2)
日常膜拜dalao 財神萬歲!話說這個線段樹今天折磨了我五個小時然後終於發現少打了乙個2.離開學還有4天然而作業一字未動絲毫不慌 ing 原題連線 洛谷線段樹模板2 要求 如題,已知乙個數列,你需要進行下面三種操作 1.將某區間每乙個數乘上x 2.將某區間每乙個數加上x 3.求出某區間每乙個數的和 ...
洛谷 P3373 模板 線段樹 2
洛谷 p3373 模板 線段樹 2 已知乙個數列,你需要進行下面三種操作 1.將某區間每乙個數乘上x 2.將某區間每乙個數加上x 3.求出某區間每乙個數的和 思路 兩個lazy標記 add和mul,怎麼下放?我遇到的問題 很多題解上來就說先乘後加比先加後乘好處理。我疑惑 如果有兩個lazy標記,不知...