bzoj 1858 SCOI2010 序列操作

2021-08-17 22:50:47 字數 1803 閱讀 1233

lxhgww最近收到了乙個01序列,序列裡面包含了n個數,這些數要麼是0,要麼是1,現在對於這個序列有五種變換操作和詢問操作:

0 a b 把[a, b]區間內的所有數全變成0

1 a b 把[a, b]區間內的所有數全變成1

2 a b 把[a,b]區間內的所有數全部取反,也就是說把所有的0變成1,把所有的1變成0

3 a b 詢問[a, b]區間內總共有多少個1

4 a b 詢問[a, b]區間內最多有多少個連續的1 對於每一種詢問操作,lxhgww都需要給出回答,聰明的程式設計師們,你們能幫助他嗎?

這道題我還能講什麼呢?相信大家都是一眼秒演算法,線段樹嘛。但這是道碼農題啊,需要維護的東西太多了。關鍵是兩個lazy標記的下放,要看哪個先再更新,就要新開個標記來記錄它的順序,之後就是套路了,具體看**。

#include

#include

#include

#include

#include

using namespace std;

struct trnode

//c1表示區間內1的個數 c2表示區間內最多有連續1的個數 c3表示示區間內最多有連續0的個數

//k1表示左端點開始連續1的個數 k2表示右端點開始連續1的個數 k3表示左端點開始連續0的個數 k4表示右端點開始連續0的個數

}tr[210000];int trlen;

int a[110000];

inline void myswap(int now,int t)

inline void xg(int now,int k,int t)

if(k==0)

}inline void update1(int now)

inline void update2(int now,int t)

inline void update3(int now,int t)

inline void update(int now)

else

}void bt(int l,int r)

else

}void change(int now,int l,int r,int k,int t)

update(now);

intlc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;

if(r<=mid)change(lc,l,r,k,t);

else

if(mid+1

<=l)change(rc,l,r,k,t);

else change(lc,l,mid,k,t),change(rc,mid+1,r,k,t);

update1(now);

}void getf(int now,int l,int r,int t)

update(now);

intlc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;

if(r<=mid)getf(lc,l,r,t);

else

if(mid+1

<=l)getf(rc,l,r,t);

else getf(lc,l,mid,t),getf(rc,mid+1,r,t);

update1(now);

}int solve1(int now,int l,int r)

int solve2(int now,int l,int r)

int main()

return

0;}

bzoj1858SCOI 序列操作 (線段樹)

題目大意 給定乙個長度為n的01序列為,現在有m種操作 0a b 0ab 把 a,b a,b 的數全部修改為0 1a b 1ab 把 a,b a,b 的數全部修改為1 2a b 2ab 把 a,b a,b 的所有數取反,就是0 1 1 0 3a b 3ab 詢問 a b a,b 中一共有多少個0 4...

bzoj1858SCOI 序列操作 (線段樹)

題目大意 給定乙個長度為n的01序列為,現在有m種操作 0 a b 把 a,b 的數全部修改為0 1 a b 把 a,b 的數全部修改為1 2 a b 把 a,b 的所有數取反,就是0 1 1 0 3 a b 詢問 a,b 中一共有多少個0 4 a b 詢問 a,b 中最長有多少個連續的1 其中 n...

bzoj1858 Scoi2010 序列操作

bzoj1858 scoi2010 序列操作 一道裸線段樹。的確是比較好想,然而 寫得莫名醜,於是調了很長時間。題解 維護區間中1的總數,左起連續1的個數,右起連續1的個數,最大連續1的個數,0同理。更新的時候左起連續1 0 要考慮左區間全為1 0 延伸到右區間的情況,右起同理。最大連續考慮左區間的...