BZOJ 1858 序列操作 線段樹

2021-09-07 23:09:37 字數 1161 閱讀 3135

題意:給乙個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)每個節點資訊:

l0,l1:左端開始連續01的個數;

r0,r1:右端開始連續01的個數;

max0,max1:區間內最長連續01的長度;

cnt0,cnt1:區間內01的個數

flag:-1表示無標記,0表示全為0,1表示全為1,2表示取反

(2)不管查詢還是更新,最主要的是當前區間的flag不是-1時,向下傳遞該狀態。

struct node

;const int max=100005;

node a[max<<2];

int n,m,p[max];

void update(int t)

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

build(t*2,l,a[t].mid);

build(t*2+1,a[t].mid+1,r);

update(t);

}void swap(int &x,int &y)

void change(int t,int l,int r,int cmd)

else if(cmd==1)

else if(cmd==2)

return;

}if(a[t].flag>=0)

if(r<=a[t].mid) change(t*2,l,r,cmd);

else if(l>a[t].mid) change(t*2+1,l,r,cmd);

else

update(t);

}node get(int t,int l,int r)

node t1,t2,t3;

if(r<=a[t].mid) return get(t*2,l,r);

else if(l>a[t].mid) return get(t*2+1,l,r);

else

}int main()}}

return 0;

}

BZOJ1858 序列操作(線段樹)

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

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

1858 scoi2010 序列操作 time limit 10 sec memory limit 64 mb description lxhgww最近收到了乙個01序列,序列裡面包含了n個數,這些數要麼是0,要麼是1,現在對於這個序列有五種變換操作和詢問操作 0 a b 把 a,b 區間內的所有數...

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