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; }