題意:給乙個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...