bzoj1858 序列操作 (線段樹區間資訊合併)

2021-07-26 06:56:08 字數 2124 閱讀 8654

1858: [scoi2010]序列操作

time limit: 10 sec  memory limit: 64 mb

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<=""div="" style="font-family: arial, verdana, helvetica,sans-serif;">

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 output52

65hint

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

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

題目分析:hotel那題的加強版。在這裡我們不僅要維護最長連續的1,還要維護0,因為它隨時可能取反。還有一點要比較注意的是各種懶惰標記之間的覆蓋與合併問題,比如乙個點原先有op=0的懶惰標記(將子樹全部變為0),再在它上面下傳乙個op=2的懶惰標記(將子樹全部取反),結果等於乙個op=1的懶惰標記(全部變為1),之類的……

code:

#include#include#include#include#include#include#includeusing namespace std;

const int maxn=100100;

struct data

;struct tnode

tree[maxn<<2];

int a[maxn];

int n,m;

void clear(int root,int l,int r,int x)

void work(int root,int l,int r,int id)

void up(int root,int l,int r)

void build(int root,int l,int r)

int left=root<<1;

int right=left|1;

int mid=(l+r)>>1;

build(left,l,mid);

build(right,mid+1,r);

up(root,l,r);

}void change(int root,int l,int r,int op)

if (op==2)

if (op==3) }

void down(int root,int l,int r)

void update(int root,int l,int r,int x,int y,int op)

int query(int root,int l,int r,int x,int y,int op)

}int main()

{ freopen("bzoj1858.in","r",stdin);

freopen("bzoj1858.out","w",stdout);

scanf("%d%d",&n,&m);

for (int i=1; i<=n; i++) scanf("%d",&a[i]);

build(1,1,n);

/*for (int i=1; i<=30; i++)

{ coutcoutcoutcoutcoutcoutcoutcoutcout<

BZOJ1858 序列操作(線段樹)

bzoj 這題思路很簡單,細節很煩,很碼 維護區間翻轉和區間賦值標記 當打到區間賦值標記時直接覆蓋掉翻轉標記 下放標記的時候先放賦值標記再放翻轉標記 這樣可以維護前4個操作 對於第5個操作 維護區間從左 右端點開始的最大連續0 1 的個數 以及區間內的最大連續0 1 的個數 做區間翻轉的時候所有的關...

BZOJ 1858 序列操作 線段樹

題意 給乙個01序列,有5種操作 1 0 l r 將 l,r 之間的數字都變成0 2 1 l r 將 l,r 之間的數字都變成1 3 2 l r 將 l r 之間的數字都取反 4 3 l r 詢問 l r 之間1的個數 5 4 l r 詢問 l,r 之間連續1的個數最大是多少 思路 1 每個節點資訊...

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...