重溫一下線段樹,聽說藍橋杯線段樹考的比較多,過來複習一下,乙個線段樹的板子題。
題目大意:
支援區間加、區間乘、區間查詢
要求時間複雜度為nlog(n)級別
顯然線段樹(樹狀陣列忘記怎麼寫了qaq~ )
如果只有區間加法或者只有區間乘法,本題將直接做標記,下放標記即可,單次修改或查詢最壞情況下時間複雜度為樹的高度,即:log(n),總體的時間複雜度為mlog(n)
而本題有加法和乘法兩種標記,所以本題的核心就是怎麼處理加法和乘法標記的關係
如上圖,可以解讀為:
(x+3)* 5 ---------------------------------------(1)
(x*5)+ 3 ---------------------------------------(2)
為了避免產生歧義我們必須規定乙個先後順序。
假設我們先算的是加法
①若: + 3 比 *5 先執行,則直接計算(1)式
②若: *5 比 + 3 先執行
此時, jia 無可避免的會乘以 cheng 很難計算出正確的數值
假設我們先算的是乘法
①若: + 3 比 *5 先執行,則我們在 * 5 的時候,對於還沒有下方的 + 3 也要進行 * 5 的計算即將(1)式拆開
x * 5 + 3 * 5 ---------------------------------------(3)
②若: *5 比 + 3 先執行,則直接計算(2)式
故,我們先處理乘法標記
xf_cheng
(root)
;//先下放
xf_jia
(root)
;//後下放
下放乘法標記
void
xf_cheng
(zt *root)
下放加法標記
void
xf_jia
(zt *root)
完整**:
#include
#include
#include
#include
using
namespace std;
typedef
long
long ll;
const
int n =
4e5+5;
struct zt
;zt tree[n]
;int n,m,p,cnt,a,x,y,k;
void
xf_cheng
(zt *root)
void
xf_jia
(zt *root)
void
build_tree
(zt *root,ll l,ll r)
void
add(zt *root,ll l,ll r,ll ql,ll qr,ll x)
xf_cheng
(root)
;xf_jia
(root)
; ll mid = l + r >>1;
if(ql <= mid)
add(root-
>lift,l,mid,ql,qr,x);if
(qr > mid)
add(root-
>right,mid +
1,r,ql,qr,x)
; root-
>sum = root-
>lift-
>sum + root-
>right-
>sum;
root-
>sum %
= p;
}void
cheng
(zt *root,ll l,ll r,ll ql,ll qr,ll x)
xf_cheng
(root)
;xf_jia
(root)
; ll mid = l + r >>1;
if(ql <= mid)
cheng
(root-
>lift,l,mid,ql,qr,x);if
(qr > mid)
cheng
(root-
>right,mid +
1,r,ql,qr,x)
; root-
>sum = root-
>lift-
>sum + root-
>right-
>sum;
root-
>sum %
= p;
}ll sum
(zt *root,ll l,ll r,ll ql,ll qr)
intmain()
for(
int i =
1;i <= m;i ++
)else
}}
洛谷P3373 模板 線段樹2
這題有毒啊,敲了我一晚上加一早上,總算a了。由於有加和乘兩個操作,要用2個lazy陣列。核心難點就是2個lazy陣列會相互影響。因為乘影響加,加不影響乘,所以我們先算乘。include include include include include include include include i...
洛谷 P3373 模板 線段樹 2
如題,已知乙個數列,你需要進行下面三種操作 1.將某區間每乙個數乘上x 2.將某區間每乙個數加上x 3.求出某區間每乙個數的和 第一行包含三個整數n m p,分別表示該數列數字的個數 操作的總個數和模數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含3或4個...
線段樹(洛谷P3373模板2)
日常膜拜dalao 財神萬歲!話說這個線段樹今天折磨了我五個小時然後終於發現少打了乙個2.離開學還有4天然而作業一字未動絲毫不慌 ing 原題連線 洛谷線段樹模板2 要求 如題,已知乙個數列,你需要進行下面三種操作 1.將某區間每乙個數乘上x 2.將某區間每乙個數加上x 3.求出某區間每乙個數的和 ...