hdu 3397 Sequence operation(线段树)

来源:互联网 发布:mac 强制删除文件夹 编辑:程序博客网 时间:2024/05/17 07:05

题目链接:hdu 3397 Sequence operation

题目大意:给定一个01序列,5种操作:

  • 0 a b:将区间a,b上的数置为0
  • 1 a b:将区间a,b上的数置为1
  • 2 a b:将区间a,b上的元素0变1,1变0
  • 3 a b:查询a,b中1的个数
  • 4 a b:查询a,b中最大连续1的个数

解题思路:区间合并+成段更新。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 100005;int N, M, a[maxn];#define lson(x) ((x)<<1)#define rson(x) (((x)<<1)|1)struct Node {    int l, r, filp, set;    int lc[2], rc[2], sc[2];    int cnt[2];    int length() {        return r - l + 1;    }    void maintain(int d) {        set = d;        filp = 0;        for (int i = 0; i < 2; i++)            lc[i] = rc[i] = sc[i] = cnt[i] = (i == d ? r - l + 1 : 0);    }    void splay() {        if (set != -1)            set ^= 1;        else            filp ^= 1;        swap(lc[0], lc[1]);        swap(rc[0], rc[1]);        swap(sc[0], sc[1]);        swap(cnt[0], cnt[1]);    }}nd[maxn << 2];void pushup(int u) {    for (int i = 0; i < 2; i++) {        nd[u].cnt[i] = nd[lson(u)].cnt[i] + nd[rson(u)].cnt[i];        nd[u].lc[i] = nd[lson(u)].lc[i] + (nd[lson(u)].lc[i] == nd[lson(u)].length() ? nd[rson(u)].lc[i] : 0);        nd[u].rc[i] = nd[rson(u)].rc[i] + (nd[rson(u)].rc[i] == nd[rson(u)].length() ? nd[lson(u)].rc[i] : 0);        nd[u].sc[i] = max(max(nd[lson(u)].sc[i], nd[rson(u)].sc[i]), nd[lson(u)].rc[i] + nd[rson(u)].lc[i]);    }}void pushdown (int u) {    if (nd[u].filp) {        nd[lson(u)].splay();        nd[rson(u)].splay();        nd[u].filp = 0;    } else if (nd[u].set != -1) {        nd[lson(u)].maintain(nd[u].set);        nd[rson(u)].maintain(nd[u].set);        nd[u].set = -1;    }}void build(int u, int l, int r) {    nd[u].l = l, nd[u].r = r;    nd[u].filp = 0, nd[u].set = -1;    if (l == r) {        nd[u].maintain(a[l]);        return;    }    int mid = (l + r) / 2;    build(lson(u), l, mid);    build(rson(u), mid + 1, r);    pushup(u);}void modify (int u, int l, int r, int v) {    if (l <= nd[u].l && nd[u].r <= r) {        nd[u].maintain(v);        return;    }    pushdown(u);    int mid = (nd[u].l + nd[u].r) / 2;    if (l <= mid)        modify(lson(u), l, r, v);    if (r > mid)        modify(rson(u), l, r, v);    pushup(u);}void modify (int u, int l, int r) {    if (l <= nd[u].l && nd[u].r <= r) {        nd[u].splay();        return;    }    pushdown(u);    int mid = (nd[u].l + nd[u].r) / 2;    if (l <= mid)        modify(lson(u), l, r);    if (r > mid)        modify(rson(u), l, r);    pushup(u);}int query_cnt(int u, int l, int r) {    if (l <= nd[u].l && nd[u].r <= r)        return nd[u].cnt[1];    pushdown(u);    int mid = (nd[u].l + nd[u].r) / 2, ret = 0;    if (l <= mid)        ret += query_cnt(lson(u), l, r);    if (r > mid)        ret += query_cnt(rson(u), l, r);    pushup(u);    return ret;}int query_len(int u, int l, int r) {    if (l <= nd[u].l && nd[u].r <= r)        return nd[u].sc[1];    pushdown(u);    int mid = (nd[u].l + nd[u].r) / 2, ret;    if (r <= mid)        ret = query_len(lson(u), l, r);    else if (l > mid)        ret = query_len(rson(u), l, r);    else {        int ll = query_len(lson(u), l, r);        int rr = query_len(rson(u), l, r);        int A = min(nd[lson(u)].rc[1], mid - l + 1);        int B = min(nd[rson(u)].lc[1], r - mid);        ret = max(max(ll, rr), A + B);    }    pushup(u);    return ret;}int main () {    int cas;    scanf("%d", &cas);    while (cas--) {        scanf("%d%d", &N, &M);        for (int i = 0; i < N; i++)            scanf("%d", &a[i]);        build(1, 0, N - 1);        int op, l, r;        while (M--) {            scanf("%d%d%d", &op, &l, &r);            if (op == 0)                modify(1, l, r, 0);            else if (op == 1)                modify(1, l, r, 1);            else if (op == 2)                modify(1, l, r);            else if (op == 3)                printf("%d\n", query_cnt(1, l, r));            else                printf("%d\n", query_len(1, l, r));        }    }    return 0;}
0 0
原创粉丝点击