計蒜客 黑白石頭 統計連續子列
阿新 • • 發佈:2019-02-07
思路就是建兩顆樹 左樹1 為黑樹 右樹0為白樹 ^=來操作懶惰標記
統計左 中 右 連續子列 完成題目要求
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MAX_N = 100005; struct node { int len; int len_l; int len_r; int down; }arr1[4*MAX_N],arr0[4*MAX_N]; void up(int p,int l,int r){ int mid = l+(r-l)/2,len_black,len_white; if(arr1[p*2].len_l==(mid-l+1)){ arr1[p].len_l = arr1[p*2+1].len_l+arr1[p*2].len_l; } else { arr1[p].len_l = arr1[p*2].len_l; } if(arr1[p*2+1].len_r==r-mid){ arr1[p].len_r = arr1[p*2+1].len_r+arr1[p*2].len_r; } else { arr1[p].len_r = arr1[p*2+1].len_r; } len_black = arr1[p*2].len_r+arr1[p*2+1].len_l; arr1[p].len=max(max(max(arr1[p*2].len_l,arr1[p*2+1].len_r),max(arr1[p*2+1].len,arr1[p*2].len)),len_black); if(arr0[p*2].len_l==(mid-l+1)){ arr0[p].len_l = arr0[p*2+1].len_l+arr0[p*2].len_l; } else { arr0[p].len_l = arr0[p*2].len_l; } if(arr0[p*2+1].len_r==r-mid){ arr0[p].len_r = arr0[p*2+1].len_r+arr0[p*2].len_r; } else { arr0[p].len_r = arr0[p*2+1].len_r; } len_white = arr0[p*2].len_r+arr0[p*2+1].len_l; arr0[p].len=max(max(max(arr0[p*2].len_l,arr0[p*2+1].len_r),max(arr0[p*2+1].len,arr0[p*2].len)),len_white); } void SWAP(int p){ int len_l = arr1[p].len_l; int len_r = arr1[p].len_r; int len_len =arr1[p].len; arr1[p].len_l = arr0[p].len_l; arr1[p].len_r = arr0[p].len_r; arr1[p].len = arr0[p].len; arr0[p].len_l = len_l; arr0[p].len_r = len_r; arr0[p].len = len_len; } void down(int p,int l,int r){ if(arr1[p].down){ arr1[p].down^=1; arr1[p*2].down^=1; arr1[p*2+1].down^=1; SWAP(p); SWAP(p*2); SWAP(p*2+1); } } void build(int p,int l,int r){ if(l==r){ scanf("%d",&arr1[p].len); if(arr1[p].len){ arr1[p].len_l = 1; arr1[p].len_r = 1; } else { arr0[p].len = 1; arr0[p].len_l = 1; arr0[p].len_r = 1; } return; } down(p,l,r); int mid =l+(r-l)/2; build(p*2,l,mid); build(p*2+1,mid+1,r); up(p,l,r); } void modify(int p,int l,int r,int x,int y){ if(x<=l&&r<=y) { arr1[p].down^=1; SWAP(p); return; } int mid = l+(r-l)/2; down(p,l,r); if(x<=mid) modify(p*2,l,mid,x,y); if(y>mid) modify(p*2+1,mid+1,r,x,y); up(p,l,r); } node query(int p,int l,int r,int x,int y){ if(x<=l&&r<=y){ return arr1[p]; } down(p,l,r); int mid = l+(r-l)/2; up(p,l,r); if(x<=mid&&y>mid){ node nod1 = query(p*2,l,mid,x,y); node nod2 = query(p*2+1,mid+1,r,x,y); node nod; if(nod1.len_l==(mid-l+1)){ nod.len_l = nod1.len_l+nod2.len_l; } else { nod.len_l = nod1.len_l; } if(nod2.len_r==r-mid){ nod.len_r = nod1.len_r+nod2.len_r; } else { nod.len_r = nod2.len_r; } int len_len = nod1.len_r+nod2.len_l; nod.len=max(max(max(nod.len_r,nod.len_l),max(nod1.len,nod2.len)),len_len); return nod; } else if(x<=mid){ return query(p*2,l,mid,x,y); } else if(x>mid){ return query(p*2+1,mid+1,r,x,y); } } int main(){ int n,m; scanf("%d",&n); build(1,1,n); scanf("%d",&m); while(m--){ int d,a,b; scanf("%d%d%d",&d,&a,&b); if(d==1){ modify(1,1,n,a,b); } else if(d==0) { printf("%d\n",query(1,1,n,a,b).len); } } return 0; }