这题不得不吐槽下了,这是我没有搜题解1a的题,让我又有继续做线段树的动力。几个东西揉在一块。
#include #include #include #include #include <string> #include #include #include #include #include <set> #include #include #include #include using namespace std; const int maxn = 111111; int color[maxn << 2], sign[maxn << 2]; int sum[maxn << 2], lsum[maxn << 2], rsum[maxn << 2]; int sum1[maxn << 2], lsum1[maxn << 2], rsum1[maxn << 2]; int ans[maxn << 2]; #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 void below(int rt, int m) { if (~color[rt]) color[rt] ^= 1; else sign[rt] ^= 1; ans[rt] = m - ans[rt]; swap(sum[rt], sum1[rt]); swap(lsum[rt], lsum1[rt]); swap(rsum[rt], rsum1[rt]);// 对于处理 0,1互换的情况,我维护两个东西,一个记录连续1,一个记录连续0。执行互换时只需要将这两部分互换即可 } void down(int rt, int m) { if (~color[rt]){ sign[rt << 1] = sign[rt << 1 | 1] = 0; color[rt << 1] = color[rt << 1 | 1] = color[rt]; if (color[rt] == 1){ ans[rt << 1] = m - (m >> 1); sum[rt << 1] = lsum[rt << 1] = rsum[rt << 1] = m - (m >> 1); sum1[rt << 1] = rsum1[rt << 1] = lsum1[rt << 1] = 0; ans[rt << 1 | 1] = (m >> 1); sum[rt << 1 | 1] = lsum[rt << 1 | 1] = rsum[rt << 1 | 1] = (m >> 1); sum1[rt << 1 | 1] = rsum1[rt << 1 | 1] = lsum1[rt << 1 | 1] = 0; } if (color[rt] == 0){ ans[rt << 1] = ans[rt << 1 | 1] = 0; sum[rt << 1] = lsum[rt << 1] = rsum[rt << 1] = sum[rt << 1 | 1] = lsum[rt << 1 | 1] = rsum[rt << 1 | 1] = 0; sum1[rt << 1] = lsum1[rt << 1] = rsum1[rt << 1] = (m - (m >> 1)); sum1[rt << 1 | 1] = lsum1[rt << 1 | 1] = rsum1[rt << 1 | 1] = (m >> 1); } color[rt] = -1; } if (sign[rt]){ below(rt << 1, (m - (m >> 1))); below(rt << 1 | 1, (m >> 1)); sign[rt] = 0; } } void up(int rt, int m) { ans[rt] = ans[rt << 1] + ans[rt << 1 | 1]; lsum[rt] = lsum[rt << 1]; rsum[rt] = rsum[rt << 1 | 1]; if (lsum[rt] == (m - (m >> 1))) lsum[rt] += lsum[rt << 1 | 1]; if (rsum[rt] == (m >> 1)) rsum[rt] += rsum[rt << 1]; sum[rt] = max(max(sum[rt << 1], sum[rt << 1 | 1]), rsum[rt << 1] + lsum[rt << 1 | 1]); lsum1[rt] = lsum1[rt << 1]; rsum1[rt] = rsum1[rt << 1 | 1]; if (lsum1[rt] == (m - (m >> 1))) lsum1[rt] += lsum1[rt << 1 | 1]; if (rsum1[rt] == (m >> 1)) rsum1[rt] += rsum1[rt << 1]; sum1[rt] = max(max(sum1[rt << 1], sum1[rt << 1 | 1]), rsum1[rt << 1] + lsum1[rt << 1 | 1]); } void build(int l, int r, int rt) { color[rt] = -1; sign[rt] = 0; if (l == r){ scanf("%d", &ans[rt]); if (ans[rt]) sum[rt] = lsum[rt] = rsum[rt] = 1, lsum1[rt] = rsum1[rt] = sum1[rt] = 0; else sum1[rt] = lsum1[rt] = rsum1[rt] = 1, sum[rt] = lsum[rt] = rsum[rt] = 0; return; } int mid = (l + r) >> 1; build(lson); build(rson); up(rt, r - l + 1); } void update(int L, int R, int add, int l, int r, int rt) { if (L <= l&&r <= R){ if (add == 1){ color[rt] = 1; sign[rt] = 0; ans[rt] = r - l + 1; sum[rt] = lsum[rt] = rsum[rt] = r - l + 1; sum1[rt] = lsum1[rt] = rsum1[rt] = 0; } if (add == 0){ color[rt] = 0; sign[rt] = 0; ans[rt] = 0; sum[rt] = lsum[rt] = rsum[rt] = 0; sum1[rt] = lsum1[rt] = rsum1[rt] = r - l + 1; } if (add == -1) below(rt,r-l+1); return; } int mid = (l + r) >> 1; down(rt, r - l + 1); if (L <= mid) update(L, R, add, lson); if (R > mid) update(L, R, add, rson); up(rt, r - l + 1); } int ask(int L, int R, int l, int r, int rt) { if (L <= l&&r <= R) return ans[rt]; down(rt, r - l + 1); int mid = (l + r) >> 1; int ret = 0; if (L <= mid) ret += ask(L, R, lson); if (R > mid) ret += ask(L, R, rson); return ret; } int ask1(int L, int R, int l, int r, int rt) { if (L <= l&&r <= R) return sum[rt]; int mid = (l + r) >> 1; down(rt, r - l + 1); int ret = 0; ret = min(mid - L + 1, rsum[rt << 1]) + min(R - mid, lsum[rt << 1 | 1]); if (L <= mid) ret = max(ret, ask1(L,R,lson)); if (R > mid) ret = max(ret, ask1(L,R,rson)); return ret; } int main() { int Icase; int n; int m; int a; int b; int c; scanf("%d", &Icase); while (Icase--){ scanf("%d%d", &n, &m); build(1, n, 1); for (int i = 0; i < m; i++){ //printf("jijidajiji%d\n", sum[1]); scanf("%d%d%d", &a, &b, &c); b++; c++; if (a == 0) update(b, c, 0, 1, n, 1); if (a == 1) update(b, c, 1, 1, n, 1); if (a == 2) update(b, c, -1, 1, n, 1); if (a == 3){ int t = ask(b, c, 1, n, 1); printf("%d\n", t); } if (a == 4){ int t = ask1(b, c, 1, n, 1); //printf("chaojixiaojiji %d\n", ask1(3, 3, 1, n, 1)); printf("%d\n", t); } } } return 0; }
转载于:https://www.cnblogs.com/yigexigua/p/3928293.html