SCOI2010 序列操作 線段樹

2022-04-29 22:36:11 字數 2820 閱讀 6766

~~~題面~~~

題解:在考場上打的這道題,出人意料的很快就打完了?!

直接用線段樹,維護幾個東西:

1,lazy標記 : 表示區間賦值

2,mark標記:表示區間翻轉

3,l1:字首最長連續的1的子段長度

4,l0:字首最長連續的0的子段長度

5,m0:區間內最長的全為0的子段的長度

6,r0:字尾最長連續的0的子段長度

7,r1:字尾最長連續的1的子段長度

8,m1:區間內最長的全為1的子段的長度

9,sum :區間和

維護起來比較繁瑣,細節較多,但是都不難,是可以自己想出來的。

這裡提乙個可以忽略標記處理順序的小技巧:

因為lazy標記是可以覆蓋mark標記的,因此乙個節點在得到lazy標記時,清空mark標記。

因為mark標記可以看做是直接對lazy標記進行翻轉,因此如果乙個節點已經有lazy標記,那麼在打上mark標記時,可以選擇不得到mark標記,而是直接對lazy標記進行修改。

因此不論是什麼情況,mark標記和lazy標記都不會同時存在,也就不會有處理的先後順序問題了。

1 #include2

using

namespace

std;

3#define r register int

4#define ac 101000

5#define ac 800000

6#define ll long long

7int

n, m, ans;

8int

s[ac];

9int

sum[ac], lazy[ac], l1[ac], r1[ac], l0[ac], r0[ac], m1[ac], m0[ac], l[ac], r[ac];

10bool

mark[ac];

1112 inline int

read()

1319

20 inline void upmin(int &a, int

b)21

2425 inline void upmax(int &a, int

b)26

2930 inline int max(int a, int

b)31

3536

void update(int x)//

更新資訊

3753

54void getlazy(int x, int

go)55

62else

if(go == 2)63

69 mark[x] = 0;//

區間賦值可以抵消區間反轉70}

7172

void getmark(int

x)7382}

8384

void pushdown(int x)//

下傳標記

8595

if(mark[x])

96101

}102

103void change(int x, int ll, int rr, int go)//

區間修改

104112

int mid = (l[x] + r[x]) >> 1

;113

if(rr <= mid) change(x * 2

, ll, rr, go);

114else

if(ll > mid) change(x * 2 + 1

, ll, rr, go);

115else

116120

update(x);

121}

122123

void getsum(int x, int ll, int

rr)124

131int mid = (l[x] + r[x]) >> 1

;132

if(rr <= mid) getsum(x * 2

, ll, rr);

133else

if(ll > mid) getsum(x * 2 + 1

, ll, rr);

134else

135139

}140

141void find(int x, int ll, int rr)//

詢問連續1的長度

142149

int mid = (l[x] + r[x]) >> 1

;150

if(rr <= mid) find(x * 2

, ll, rr);

151else

if(ll > mid) find(x * 2 + 1

, ll, rr);

152else

153159

}160

161void build(int x, int ll ,int

rr)162

170int mid = (ll + rr) >> 1

;171 build(x * 2

, ll, mid);

172 build(x * 2 + 1, mid + 1

, rr);

173update(x);

174}

175176

void

pre()

177181

182void

work()

183198

else

if(opt == 4

)199

204}

205}

206207

intmain()

208

view code

SCOI2010 序列操作 分塊or線段樹

include include define lc k 1 define rc k 1 1 using namespace std const int n 1e5 5 int n,m,a n struct sgts,tr n 2 inline intread while ch 0 ch 9 retu...

SCOI2010 序列操作

我可以銘記一生的蛇皮線段樹 左左右右上上下下中間兩頭 咳咳,沒什麼好說的了,開始寫吧。我,可真是,寫了zz三天。include include includeusing namespace std struct ans int n,q,a 4000101 int sum 4000101 l1 400...

1858 Scoi2010 序列操作

1858 scoi2010 序列操作 time limit 10 sec memory limit 64 mb submit 3397 solved 1624 submit status discuss description lxhgww最近收到了乙個01序列,序列裡面包含了n個數,這些數要麼是0...