使用線段樹維護 b
bb, 初值為 −bi
-b_i
−bi
, 每次修改時, 若乙個位置上的值變為了 0
00, 則說明其會對答案產生新的貢獻,
在外部使用樹狀陣列將貢獻計入答案, 然後將該位置的值 重置為 −bi
-b_i
−bi
, 重置的時間複雜度是 o
(logn
)o(\log n)
o(logn) .
考慮最壞情況, 每次操作 [1,
n]
[1, n]
[1,n],
這樣 bi=
1b_i=1
bi=
1 的位置最多重置 n
nn 次 bi=
2b_i=2
bi=
2 最多重置 n
2\frac
2n 次, bi=
3b_i=3
bi=
3 最多 …
所以總共需要 重置 o(n
logn)
o(n \log n)
o(nlogn)
次,總時間複雜度o(n
log2n
)o(n \log^2 n)
o(nlog2n
) .重置 可以在 修改 時 使用 upd
ate(
)update()
update
()實現 .
#include
#define reg register
#define fi first
#define se second
typedef std::pair<
int,
int> pr;
intread()
while
(isdigit
(c)) s = s*
10+ c-
'0', c =
getchar()
;return s * flag;
}const
int maxn =
100005
;const
int inf =
0x3f3f3f3f
;int n;
int m;
int tmp_1;
int b[maxn]
;struct bit_tree
intquery
(int k)
} bit_t;
struct segment_tree t[maxn <<2]
;void
push_down
(const
int&k)
void
push_up
(const
int&k)
void
build
(int k,
int l,
int r)
void
update
(int k)
void
modify
(int k,
const
int&ql,
const
int&qr,
const
int&aim)
modify
(k<<
1, ql, qr, aim)
,modify
(k<<1|
1, ql, qr, aim)
;push_up
(k);
}int
query
(int k,
const
int&ql,
const
int&qr)
} seg_t;
intmain()
return0;
}
序列操作(線段樹)
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 將...
線段樹 維護序列
老師交給小可可乙個維護數列的任務,現在小可可希望你來幫他完成。有長為 n 的數列,不妨設為 a1,a2,an。有如下三種操作形式 把數列中的一段數全部乘乙個值 把數列中的一段數全部加乙個值 詢問數列中的一段數的和,由於答案可能很大,你只需輸出這個數模 p 的值。輸入格式 第一行兩個整數 n 和 p ...