輸入:
10 10
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9
輸出:52
65思路:核心:線段樹、模擬
首先確定要維護的資訊,要查區間1的數量,最大連續1的長度,又有取反操作(0和1資訊交換)。
所以最好0和1的資訊都要維護。對於0和1我開了個陣列分別存資訊,因為對0和1的操作類似,用個for(0->1)少寫點**~
維護區間0和1的數量,最大連續0和1的長度。
連續長度可能還有出現在區間合併中,所以還要維護區間兩端的0和1向中間連續擴充套件的長度。
還有一些說明在**注釋中談及。
記得向下傳遞lazy標記時,消除自身lazy標記!!!
(挺麻煩的一道線段樹×
#include
#define ios std::ios_base::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
using
namespace std;
typedef
long
long ll;
const
int n=
100100
;struct ty //線段樹維護的量
tree[
4*n]
;int a[n]
;void
pushup
(int p,
int l,
int r)
}void
build
(int p,
int l ,
int r)
int mid =
(l+r)/2
;build
(p *
2, l, mid)
;build
(p *2+
1, mid+
1, r)
;pushup
(p, l, r);}
void
pushdown
(int p,
int l,
int r)
else
}void
change
(int p,
int l,
int r,
int a,
int b ,
int x)
//區級修改,操作01
if( tree[p]
.lazy !=3)
pushdown
(p,l,r)
;int mid=
(l+r)
>>1;
if( a <= mid )
change(2
*p ,l, mid ,a ,b,x);if
( b > mid )
change(2
*p+1
,mid+
1,r, a ,b ,x)
;pushup
(p,l,r);}
void
revers
(int p,
int l,
int r,
int a ,
int b)
int mid=
(l+r)
>>1;
if( tree[p]
.lazy!=3)
pushdown
(p,l,r);if
( a <= mid )
revers(2
*p ,l, mid ,a ,b);if
( b > mid )
revers(2
*p+1
,mid+
1,r, a ,b)
;pushup
(p,l,r);}
intfindsum
(int p,
int l,
int r,
int x,
int y)
struct ty2
;ty2 findmax
(int p ,
int l,
int r,
int a,
int b)
int mid =
(l+r)/2
;if(tree[p]
.lazy !=3)
pushdown
(p, l, r);if
(b <= mid)
return
findmax
(p*2
, l, mid, a, b);if
(a > mid)
return
findmax
(p*2+1
, mid+
1, r, a, b)
; ty2 left =
findmax
(p*2
, l, mid, a, mid)
; ty2 right =
findmax
(p*2+1
, mid+
1, r, mid+
1, b)
; ans.mx =
max(
max(left.mx, right.mx)
,left.r+right.l);if
(left.l ==
(mid-l+1)
) ans.l = left.l+right.l;
else ans.l = left.l;
if(right.l ==
(r-(mid+1)
+1)) ans.r = left.r+right.r;
else ans.r = right.r;
return ans;
}int
main()
}
BZOJ2962 序列操作
題目大意 給定n個數,要求支援區間加,區間取相反數,區間查詢任意選c c 20 個數的所有方案中乘積的和 和維護k次方的和很像,想要維護選c個數,就要把選1 c個數的方案全部維護出來 這樣當合併兩個區間的時候 pushup 只需要列舉左右區間分別取了幾個數即可 現在考慮兩種修改操作 1.區間取相反數...
bzoj2962 序列操作
有乙個長度為n的序列,有三個操作1.i a b c表示將 a,b 這一段區間的元素集體增加c,2.r a b表示將 a,b 區間內所有元素變成相反數,3.q a b c表示詢問 a,b 這一段區間中選擇c個數相乘的所有方案的和mod 19940417的值。第一行兩個數n,q表示序列長度和操作個數。第...
2017 9 10 序列操作 思考記錄
唉,怎麼說呢 pushdown要注意的事全忘光了 寫 調竟然花了兩個小時 要注意反轉時是 1而不是 1!下傳標記不要單純管順序,因為沒有任何意義,要確保在任意時刻乙個點只有一種同級標記!比如賦值和反轉就是一級的 順序可以換 但加減和乘除是兩級的,因為可以規定先加減再乘除 就不會影響了 碼 為什麼我寫...