http://acm.hdu.edu.cn/showproblem.php?pid=3911
多校(8)
題意:給定一個數組元素只有0和1,然後有兩種操作,1 i j表示更改[i, j]的所有元素,0 i j表示求[i, j]裏面的最長的連續1的串的長度。。。
分析:
設置了巨多的參數啊。。。維護了某一段的最左端連續的0個數,連續的1個數,最右端連續0的個數連續1的個數,整段最長的連續0的個數和最長的連續1的個數,然後設置一個標記值cnt,記錄該節點更新的次數,每次更新只更新到段,記錄到cnt裏面,然後每次更新或查找往下找都將cnt往下更新。。。寫起來巨繁瑣啊。。。
糾結了一個下午啊啊啊。。。寫起來搞死人。。。漏掉一點點都要鬱悶死人。。。特別是求ans那個地方的錯誤好不容易找到。。
巨戳的代碼: 再寫了一遍,還是不能迅速無誤的寫出來啊。。。多練手速。。
#include<iostream> using namespace std; const int N=100010; int n, m; struct node { int l, r, mid; int max1, max0, llen, rlen; bool lcolor, rcolor, cnt; } a[N*4], tmp1, tmp2; int _max(int a, int b) { return a>b ? a:b; } int _min(int a, int b) { return a<b ? a:b; } void build(int l, int r, int p) { a[p].l = l; a[p].r = r; a[p].mid = (l+r)>>1; a[p].max0 = a[p].llen = a[p].rlen = (r-l+1); a[p].max1 = 0; a[p].lcolor = 0; a[p].rcolor = 0; a[p].cnt = 0; if(l==r) return; build(l, a[p].mid, p*2); build(a[p].mid+1, r, p*2+1); } void change(node &a) { if(a.cnt==0) return; swap(a.max0, a.max1); a.lcolor ^= 1; a.rcolor ^= 1; } void update(int l, int r, int p) { if(a[p].l==l && a[p].r==r) { a[p].cnt ^= 1; return; } if(a[p].cnt==1) { a[p*2].cnt ^= a[p].cnt; a[p*2+1].cnt ^= a[p].cnt; a[p].cnt = 0; } if(r<=a[p].mid) update(l, r, p*2); else if(l>a[p].mid) update(l, r, p*2+1); else { update(l, a[p].mid, p*2); update(a[p].mid+1, r, p*2+1); } tmp1 = a[p*2]; tmp2 = a[p*2+1]; change(tmp1); change(tmp2); a[p].lcolor = tmp1.lcolor; a[p].rcolor = tmp2.rcolor; a[p].llen = tmp1.llen; a[p].rlen = tmp2.rlen; a[p].max0 = _max(tmp1.max0, tmp2.max0); a[p].max1 = _max(tmp1.max1, tmp2.max1); if(tmp1.rcolor==tmp2.lcolor) { if(tmp1.llen==tmp1.r-tmp1.l+1) a[p].llen += tmp2.llen; if(tmp2.rlen==tmp2.r-tmp2.l+1) a[p].rlen += tmp1.rlen; if(tmp1.rcolor==0) a[p].max0 = _max(a[p].max0, tmp1.rlen+tmp2.llen); else a[p].max1 = _max(a[p].max1, tmp1.rlen+tmp2.llen); } } int query(int l, int r, int p) { if(a[p].l==l && a[p].r==r) { if(a[p].cnt==0) return a[p].max1; else return a[p].max0; } if(a[p].cnt==1) { a[p*2].cnt ^= a[p].cnt; a[p*2+1].cnt ^= a[p].cnt; } int ans; if(r<=a[p].mid) ans = query(l, r, p*2); else if(l>a[p].mid) ans = query(l, r, p*2+1); else { ans = _max(query(l,a[p].mid, p*2), query(a[p].mid+1, r, p*2+1)); tmp1 = a[p*2]; tmp2 = a[p*2+1]; change(tmp1); change(tmp2); if(tmp1.rcolor==1 && tmp2.lcolor==1) { int l1, l2; l1 = _min(a[p].mid-l+1, tmp1.rlen); l2 = _min(r-a[p].mid, tmp2.llen); ans = _max(ans, l1+l2); } } if(a[p].cnt==0) return ans; tmp1 = a[p*2]; tmp2 = a[p*2+1]; change(tmp1); change(tmp2); a[p].lcolor = tmp1.lcolor; a[p].rcolor = tmp2.rcolor; a[p].llen = tmp1.llen; a[p].rlen = tmp2.rlen; a[p].max0 = _max(tmp1.max0, tmp2.max0); a[p].max1 = _max(tmp1.max1, tmp2.max1); if(tmp1.rcolor==tmp2.lcolor) { if(tmp1.llen==tmp1.r-tmp1.l+1) a[p].llen += tmp2.llen; if(tmp2.rlen==tmp2.r-tmp2.l+1) a[p].rlen += tmp1.rlen; if(tmp1.rcolor==0) a[p].max0 = _max(a[p].max0, tmp1.rlen+tmp2.llen); else a[p].max1 = _max(a[p].max1, tmp1.rlen+tmp2.llen); } a[p].cnt = 0; return ans; } int main() { int i, j, k, op, x, y; while(scanf("%d", &n)!=EOF) { build(1, n, 1); for(i=1; i<=n; i++) { scanf("%d", &x); if(x==1) update(i, i, 1); } scanf("%d", &m); while(m--) { scanf("%d%d%d", &op, &x, &y); if(op==0) printf("%d\n", query(x, y, 1)); else update(x, y, 1); } } return 0; }