首页 > 代码库 > Hdu3397Sequence operation线段树

Hdu3397Sequence operation线段树

  

#include <cstdio>#include <cstring>#include <algorithm>#include <climits>#include <string>#include <iostream>#include <map>#include <cstdlib>#include <list>#include <set>#include <queue>#include <stack>#include<math.h>#include<vector>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|1void 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]);}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;}