給乙個長度為n
nn的序列a1,
a2,…
an
a_1,a_2,\dots a_n
a1,a2
,…a
n,你需要支援以下兩種操作:
操作1:l r x y,對所有的l≤n
≤r
l \leq n \leq r
l≤n≤
r賦值ai=
min(
ai,(
i−l)
∗y+x
)a_i = min(a_i, (i - l) * y + x)
ai=mi
n(ai
,(i
−l)∗
y+x)
。其中l,r,x,y均為整數,且有 1≤l
≤r≤n
1\leq l \leq r\leq n
1≤l≤r≤
n,∣x∣≤
100000
\left| x\right|\leq 100000
∣x∣≤10
0000
,∣ y∣
≤5
\left| y\right|\le 5
∣y∣≤5。
操作 2:x
xx,詢問a
xa_x
ax 的值,這裡 x
xx 是整數,且有1≤x
≤n
1\le x\le n
1≤x≤n。
1 ≤n
,q≤1
05
1 \leq n,q \leq 10^5
1≤n,q≤
105−10
5≤ai
≤105
-10^5 \leq a_i \leq 10^5
−105≤a
i≤1
05首先觀察a
ia_i
ai的表示式(i−
l)∗y
+x
(i - l) * y + x
(i−l)∗
y+x,我們可以對其進行化簡,即:i∗y
+(x−
l∗y)
i * y + (x - l * y)
i∗y+(x
−l∗y
)。我們觀察到y
yy的取值範圍特別小,於是我們就可以開11
1111
個線段樹去維護,每乙個線段樹代表乙個y
yy,這樣表示式中的y
yy就固定了。因為i∗y
i*yi∗
y是定值,因此我們可以放到最後直接加上,那麼原問題就等價於處理x−l
∗y
x - l * y
x−l∗
y in
,laz
ymin,lazy
min,la
zy,這裡的laz
ylazy
lazy
指的是修改後的最小值標記。
在查詢答案的過程中,遍歷每乙個線段樹,找到其中的最小值再加上i∗y
i*yi∗
y,最後再與a
ia_i
ai找乙個最小值,就是最終的答案了。
#include
#include
#include
#include
using
namespace std;
const
int n =
100010
, inf =
0x3f3f3f3f
;int n, q;
int w[n]
;struct node
tr[n *4]
[11];
void
pushup
(int k,
int u)
void
pushdown
(int k,
int u)
}void
build
(int k,
int u,
int l,
int r);if
(l==r)
return
;else
}void
modify
(int k,
int u,
int l,
int r,
int x)
else
}int
query
(int k,
int u,
int x)
intmain()
else
}return0;
}
序列 線段樹
使用線段樹維護 b bb,初值為 bi b i bi 每次修改時,若乙個位置上的值變為了 0 00,則說明其會對答案產生新的貢獻,在外部使用樹狀陣列將貢獻計入答案,然後將該位置的值 重置為 bi b i bi 重置的時間複雜度是 o log n o log n o logn 考慮最壞情況,每次操作 ...
序列操作(線段樹)
lxhgww 最近收到了乙個 01 序列,序列裡面包含了 n 1 n 105 個數,這些書要麼是 0,要麼是 1,現在對這個序列有五種變換操作和詢問操作 0 a b 把 a,b 區間內所有數全部變成 0。1 a b 把 a,b 區間內所有數全部變成 1。2 a b 把 a,b 區間內所有數全部取反,...
序列操作 線段樹
題目大意 你要維護乙個長度為n的序列,進行操作。對於這個序列,233之類的數不能出現,也就是說233,2333,23333,233333 這一系列的數不能在序列中出現。1 i 輸出第i個元素。2 a b x 將 a,b 區間的序列賦值為x。3 a b x 將 a,b 區間的序列加上x。4 a b 將...