bzoj 1858 线段树
Posted cjlhy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1858 线段树相关的知识,希望对你有一定的参考价值。
思路:很明显的线段树,随便搞搞lazy标记,维护一下区间最长的1。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 1e5 + 7; const int M = 5e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1000000007; int n, m, lazy[N << 2]; struct info { int m, l, r, s, w; info(){}; info(int _m, int _l, int _r, int _s, int _w) { m = _m; w = _w; l = _l; r = _r; s = _s; } info operator + (const info &t) const { return info(max(max(m,t.m),r+t.l),l+(l==w)*t.l,t.r+(t.r==t.w)*r,s+t.s,w+t.w); } void change(int type) { if(!type) m = l = r = s = 0; else m = l = r = s = w; } } a[N << 2], b[N << 2]; void pushdown(int rt, int l = 0, int r = 0) { if(!lazy[rt]) return; if(lazy[rt] == 1) { swap(a[rt << 1], b[rt << 1]); swap(a[rt << 1 | 1], b[rt << 1 | 1]); lazy[rt << 1] ^= 1; lazy[rt << 1 | 1] ^= 1; } else { int c = lazy[rt] - 2; a[rt << 1].change(c); b[rt << 1].change(c^1); a[rt << 1 | 1].change(c); b[rt << 1 | 1].change(c^1); lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt]; } lazy[rt] = 0; } void build(int l, int r, int rt) { if(l == r) { a[rt].w = b[rt].w = 1; int x; scanf("%d", &x); a[rt].change(x); b[rt].change(x^1); return; } int mid = l + r >> 1; build(l, mid, rt << 1); build(mid + 1, r, rt << 1 | 1); a[rt] = a[rt << 1] + a[rt << 1 | 1]; b[rt] = b[rt << 1] + b[rt << 1 | 1]; } void update(int L, int R, int c, int l, int r, int rt) { if(l >= L && r <= R) { if(c == 1) { swap(a[rt], b[rt]); lazy[rt] ^= 1; } else { a[rt].change(c-2); b[rt].change((c-2)^1); lazy[rt] = c; } return; } int mid = l + r >> 1; pushdown(rt, l, r); if(L <= mid) update(L, R, c, l, mid, rt << 1); if(R > mid) update(L, R, c, mid + 1, r, rt << 1 | 1); a[rt] = a[rt << 1] + a[rt << 1 | 1]; b[rt] = b[rt << 1] + b[rt << 1 | 1]; } info query(int L, int R, int l, int r, int rt) { if(l >= L && r <= R) return a[rt]; int mid = l + r >> 1; pushdown(rt); if(R <= mid) return query(L, R, l, mid, rt << 1); if(L > mid) return query(L, R, mid + 1, r, rt << 1 | 1); return query(L, R, l, mid, rt << 1) + query(L, R, mid + 1, r, rt << 1 | 1); } int main() { scanf("%d%d", &n, &m); build(1, n, 1); while(m--) { int op, L, R; scanf("%d%d%d", &op, &L, &R); L++; R++; if(op == 0) { update(L, R, 2, 1, n, 1); } else if(op == 1) { update(L, R, 3, 1, n, 1); } else if(op == 2) { update(L, R, 1, 1, n, 1); } else if(op == 3) { printf("%d ", query(L, R, 1, n, 1).s); } else { printf("%d ", query(L, R, 1, n, 1).m); } } return 0; } /* 10 10 0 0 0 1 1 0 1 0 1 1 1 0 2 2 2 2 */
以上是关于bzoj 1858 线段树的主要内容,如果未能解决你的问题,请参考以下文章