HDU 3397 Sequence operation

来源:互联网 发布:dts音效软件怎么下载 编辑:程序博客网 时间:2024/05/22 17:48

区间合并。5种操作,区间置1,置0,取反,询问区间1的个数和最长连续1的个数。

分别记录区间连续1,连续0,1的总个数,及0的总个数。标记3种操作时要注意顺序和逻辑。比如置1置0都能取消取反标志。

把出现过一遍以上的代码块拿出去写成函数,会使代码更简短,易维护。

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<string>#include<queue>#include<map>///LOOP#define REP(i, n) for(int i = 0; i < n; i++)#define FF(i, a, b) for(int i = a; i < b; i++)#define FFF(i, a, b) for(int i = a; i <= b; i++)#define FD(i, a, b) for(int i = a - 1; i >= b; i--)#define FDD(i, a, b) for(int i = a; i >= b; i--)///INPUT#define RI(n) scanf("%d", &n)#define RII(n, m) scanf("%d%d", &n, &m)#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)#define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)#define RFI(n) scanf("%lf", &n)#define RFII(n, m) scanf("%lf%lf", &n, &m)#define RFIII(n, m, k) scanf("%lf%lf%lf", &n, &m, &k)#define RFIV(n, m, k, p) scanf("%lf%lf%lf%lf", &n, &m, &k, &p)#define RS(s) scanf("%s", s)///OUTPUT#define PN printf("\n")#define PI(n) printf("%d\n", n)#define PIS(n) printf("%d ", n)#define PS(s) printf("%s\n", s)#define PSS(s) printf("%s ", s)#define PC(n) printf("Case %d: ", n)///OTHER#define PB(x) push_back(x)#define CLR(a, b) memset(a, b, sizeof(a))#define CPY(a, b) memcpy(a, b, sizeof(b))#define display(A, n, m) {REP(i, n){REP(j, m)PIS(A[i][j]);PN;}}#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1using namespace std;typedef long long LL;typedef pair<int, int> P;const int MOD = 1e9+7;const int INFI = 1e9 * 2;const LL LINFI = 1e17;const double eps = 1e-6;const int N = 111111;const int M = N << 2;const int move[8][2] = {0, 1, 0, -1, 1, 0, -1, 0, 1, 1, 1, -1, -1, 1, -1, -1};int lsum[M][2], rsum[M][2], msum[M][2], sum[M][2], col[M][2], L, R, a3, a4;void pushup(int m, int rt){    REP(i, 2)    {        sum[rt][i] = sum[rt << 1][i] + sum[rt << 1 | 1][i];        lsum[rt][i] = lsum[rt << 1][i];        rsum[rt][i] = rsum[rt << 1 | 1][i];        if(lsum[rt][i] == (m - (m >> 1)))lsum[rt][i] += lsum[rt << 1 | 1][i];        if(rsum[rt][i] == (m >> 1))rsum[rt][i] += rsum[rt << 1][i];        msum[rt][i] = max(lsum[rt << 1 | 1][i] + rsum[rt << 1][i], max(msum[rt << 1][i], msum[rt << 1 | 1][i]));    }}void get(int rt, int k, int a, int b){    lsum[rt][0] = rsum[rt][0] = msum[rt][0] = sum[rt][0] = k ? a : b;    lsum[rt][1] = rsum[rt][1] = msum[rt][1] = sum[rt][1] = k ? b : a;}void __swap(int rt){    swap(lsum[rt][0], lsum[rt][1]);    swap(rsum[rt][0], rsum[rt][1]);    swap(msum[rt][0], msum[rt][1]);    swap(sum[rt][0], sum[rt][1]);}void build(int l, int r, int rt){    col[rt][0] = -1;col[rt][1] = 0;    if(l == r)    {        int k;        RI(k);        get(rt, k, 0, 1);        return;    }    int m = (l + r) >> 1;    build(lson);    build(rson);    pushup(r - l + 1, rt);}void pushdown(int m, int rt){    if(col[rt][0] != -1)    {        col[rt << 1][0] = col[rt << 1 | 1][0] = col[rt][0];        col[rt << 1][1] = col[rt << 1 | 1][1] = 0;        get(rt << 1, col[rt][0], 0, m - (m >> 1));        get(rt << 1 | 1, col[rt][0], 0, m >> 1);        col[rt][0] = -1;    }    if(col[rt][1])    {        col[rt][1] = 0;        __swap(rt << 1);        __swap(rt << 1 | 1);        col[rt << 1][1] ^= 1;        col[rt << 1 | 1][1] ^= 1;    }}void update(int c, int l, int r, int rt){    if(L <= l && r <= R)    {        if(c == 2)        {            __swap(rt);            col[rt][1] ^= 1;        }        else        {            col[rt][1] = 0;            col[rt][0] = c;            get(rt, col[rt][0], 0, r - l + 1);        }        return;    }    pushdown(r - l + 1, rt);    int m = (l + r) >> 1;    if(L <= m)update(c, lson);    if(R > m) update(c, rson);    pushup(r - l + 1, rt);}int query(int l, int r, int rt){    if(L <= l && r <= R)    {        a3 += sum[rt][1];        return msum[rt][1];    }    pushdown(r - l + 1, rt);    int m = (l + r) >> 1, ans = 0;    if(L <= m)ans = max(query(lson), ans);    if(R > m) ans = max(query(rson), ans);    if(L <= m && m < R)    {        int t1 = min(rsum[rt << 1][1], m - L + 1);        int t2 = min(lsum[rt << 1 | 1][1], R - m);        ans = max(ans, t1 + t2);    }    pushup(r - l + 1, rt);    return ans;}int main(){    //freopen("input.txt", "r", stdin);    //freopen("output.txt", "w", stdout);    int t, n, m, op;    RI(t);    while(t--)    {        RII(n, m);        build(0, n - 1, 1);        while(m--)        {            RIII(op, L, R);            if(op < 3)update(op, 0, n - 1, 1);            else            {                a3 = a4 = 0;                a4 = query(0, n - 1, 1);                if(op == 3)PI(a3);                else PI(a4);            }        }    }    return 0;}