poj 3225(线段树)

来源:互联网 发布:淘宝网自助开通 编辑:程序博客网 时间:2024/05/16 13:52

线段树,用 a*2 代表 a 这个点,a*2+1 代表  (a, a+1) 这一段。

五种操作都归结于区间 T 内外的覆盖和取反。具体情况参见一下代码。

#include <iostream>
using namespace std;

#define LEN     (65536+1)*2
#define LS      (rt*2)
#define RS      (rt*2+1)
#define lson    rt*2, l, (l+r)/2
#define rson    rt*2+1, (l+r)/2+1, r

#define NONE    0
#define COV     1
#define REV     2

struct ST{short f, m;} tt[LEN*4];
int seg[LEN] = {0};
char kh[2][2] = {{'[','('}, {')',']'}};

void DoRev(int rt){
    switch (tt[rt].m){
        case COV:  tt[rt].f = 1-tt[rt].f; break;
        case REV:  tt[rt].m = 0;          break;
        case NONE: tt[rt].m = REV;        break;
    }
}
void pushdown(int rt){
    if (tt[rt].m == COV){
        tt[LS].f = tt[RS].f = tt[rt].f;
        tt[LS].m = tt[RS].m = tt[rt].m;
    }
    if (tt[rt].m == REV){
        DoRev(LS);
        DoRev(RS);
    }
    tt[rt].m = 0;
}
void make_in(char op, int rt){
    if (op == 'U') { tt[rt].f=1; tt[rt].m=COV; return; }
    if (op == 'D') { tt[rt].f=0; tt[rt].m=COV; return; }
    if (op == 'C') { DoRev(rt); return; }
    if (op == 'S') { DoRev(rt); return; }
}
void make_out(char op, int rt){
    if (op == 'I') { tt[rt].f=0; tt[rt].m=COV; return; }
    if (op == 'C') { tt[rt].f=0; tt[rt].m=COV; return; }
}
void pushall(int rt, int l, int r){
    if (tt[rt].m == COV || l == r){
        for (int i=l; i<=r; i++) seg[i]=tt[rt].f;
        return;
    }
    pushdown(rt);
    pushall(lson);
    pushall(rson);
}
void update(char op, int b, int e, int rt, int l, int r)
{
    if (b > r || e < l)   { make_out(op, rt); return; }
    if (b <= l && r <= e) { make_in(op, rt);  return; }
    pushdown(rt);
    update(op, b, e, lson);
    update(op, b, e, rson);
}

void output(){
    int b=0, e, fir = 1;
    while (b < LEN){
        while (!seg[b]) b++;
        if (b > LEN) break;
        for (e=b; seg[e+1] && e+1<LEN; e++);

        (fir)?  fir=0 : printf(" ");
        printf("%c%d,%d%c", kh[0][b%2], b/2, (e+1)/2, kh[1][(e+1)%2]);
        b=e+1;
    }
    if (fir) printf("empty set");
    printf("\n");
}

int main()
{
    memset(tt, 0, sizeof(tt));
    tt[1].m = COV;
    char op, cl, cr;
    int b, e;
    while (cin>>op){
        scanf(" %c%d,%d%c", &cl, &b, &e, &cr);
        b = (cl=='[')?  b*2 : b*2+1;
        e = (cr==')')?  e*2-1 : e*2;
        if (b > e){
            if (op=='I' || op=='C') { tt[1].f=0; tt[1].m=COV; }
        }else
            update(op, b, e, 1, 0, LEN);
    }
    pushall(1, 0, LEN);
    output();
    return 0;
}

原创粉丝点击