1858 Scoi2010 序列操作

2021-08-21 14:21:00 字數 2397 閱讀 2742

1858: [scoi2010]序列操作

time limit: 10 sec memory limit: 64 mb

submit: 3397 solved: 1624

[submit][status][discuss]

description

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都需要給出回答,聰明的程式設計師們,你們能幫助他嗎?

input

輸入資料第一行包括2個數,n和m,分別表示序列的長度和運算元目 第二行包括n個數,表示序列的初始狀態 接下來m行,每行3個數,op, a, b,(0 < = op < = 4,0 < = a < = b)

output

對於每乙個詢問操作,輸出一行,包括1個數,表示其對應的答案

sample input

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

sample output

5hint

對於30%的資料,1<=n, m<=1000 對於100%的資料,1< = n, m < = 100000

比較好的線段樹題,對於操作0,1,2,我們可以打三個lazy標記。注意下放的時候應該先下放0,1標記,再下放翻轉標記。而更新時如果是0,1標記,要將其他標記清空。

對於操作3我們可以維護乙個sum陣列表示區間內1的個數,直接輸出即可。對於操作4,我的做法可能比較複雜,我維護了6個陣列,分別是從左向右,從右向左,整個區間的最大0/1個數(不知道的跳轉spoj gss1),為什麼要維護0,因為這樣翻轉操作直接swap即可,**量較大,細節較多。

#include

#include

using namespace std;

const int maxn = 100005;

inline int rd()

while(isdigit(ch))

return x*f;

}int n,m,a[maxn],l[maxn<<2],r[maxn<<2],lx0[maxn<<2],rx0[maxn<<2];

int lazy0[maxn<<2],lazy1[maxn<<2],rev[maxn<<2],mx0[maxn<<2];

intsum[maxn<<2],lx1[maxn<<2],mx1[maxn<<2],rx1[maxn<<2];

int ans,lx,rx,mx,sum,ll,rr;

inline void pushdown(int x)

if(lazy1[x])

if(rev[x])

}inline void pushup(int x)

inline void build(int x,int l,int r)

int mid=l+r>>1;

build(x<<1,l,mid);build(x<<1|1,mid+1,r);

pushup(x);

}inline void update(int x,int l,int r,int ql,int qr,int k)

if(kk==0)

if(kk==1)

return;

}int mid=l+r>>1;

pushdown(x);

if(ql<=mid) update(x<<1,l,mid,ql,qr,k);

if(qr>mid) update(x<<1|1,mid+1,r,ql,qr,k);

pushup(x);

}inline int query1(int x,int l,int r,int ql,int qr)

inline void merge(int x)

inline void query2(int x,int l,int r,int ql,int qr)

int mid=l+r>>1;

pushdown(x);

if(ql<=mid) query2(x<<1,l,mid,ql,qr);

if(qr>mid) query2(x<<1|1,mid+1,r,ql,qr);

}int main()

}return

0;}

bzoj1858 Scoi2010 序列操作

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

BZOJ1858 Scoi2010 序列操作

description lxhgww最近收到了乙個01序列,序列裡面包含了n個數,這些數要麼是0,要麼是1,現在對於這個序列有五種變換操作和詢問操作 0 a b 把 a,b 區間內的所有數全變成0 1 a b 把 a,b 區間內的所有數全變成1 2 a b 把 a,b 區間內的所有數全部取反,也就是...

bzoj 1858 SCOI2010 序列操作

lxhgww最近收到了乙個01序列,序列裡面包含了n個數,這些數要麼是0,要麼是1,現在對於這個序列有五種變換操作和詢問操作 0 a b 把 a,b 區間內的所有數全變成0 1 a b 把 a,b 區間內的所有數全變成1 2 a b 把 a,b 區間內的所有數全部取反,也就是說把所有的0變成1,把所...