POJ 3225 Help with Intervals 线段树

这是道比较经典的线段树    详情可以参考http://www.notonlysuccess.com/index.php/segment-tree-complete/ sha崽大神的bolg

但需要注意的就是区间到点的转化了。 要保证转化后的区间满足集合的基本性质,比如删除一些区间后相应的点被删除,有可能会点删除完了,区间却还有,这就不符合了。

所以就要把每个点乘以二之类的,还有一些细节,注意一下

/*
ID: sdj22251
PROG: inflate
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define MAXN 66666*2
#define INF 1000000000
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
bool used[MAXN + 5];
struct node
{
    int left, right, mid;
    int Xor, Cover;
}tree[4 * MAXN];
void make_tree(int s, int e, int C)
{
    tree[C].left = s;
    tree[C].right = e;
    tree[C].mid = (s + e) >> 1;
    tree[C].Xor = tree[C].Cover = 0;
    if(s == e) return;
    make_tree(s, tree[C].mid, L(C));
    make_tree(tree[C].mid + 1, e, R(C));
}
void fun_xor(int C)
{
    if(tree[C].Cover != -1) tree[C].Cover ^= 1;
    else tree[C].Xor ^= 1;
}
void down(int C)
{
    if(tree[C].Cover != -1)
    {
        tree[L(C)].Cover = tree[R(C)].Cover = tree[C].Cover;
        tree[L(C)].Xor = tree[R(C)].Xor = 0;
        tree[C].Cover = -1;
    }
    if(tree[C].Xor)
    {
        fun_xor(L(C));
        fun_xor(R(C));
        tree[C].Xor = 0;
    }
}
void update(int s, int e, int C, char op)
{
    if(tree[C].left >= s && tree[C].right <= e)
    {
        if(op == 'U')
        {
            tree[C].Cover = 1;
            tree[C].Xor = 0;
        }
        else if(op == 'D')
            tree[C].Xor = tree[C].Cover = 0;
        else if(op == 'C' || op == 'S')
            fun_xor(C);
        return;
    }
    down(C);
    if(tree[C].mid >= s) update(s, e, L(C), op);
    else if(op == 'I' || op == 'C') tree[L(C)].Xor = tree[L(C)].Cover = 0;
    if(tree[C].mid < e) update(s, e, R(C), op);
    else if(op == 'I' || op == 'C') tree[R(C)].Xor = tree[R(C)].Cover = 0;
}
void query(int C)
{
    if(tree[C].Cover == 1)
    {
        for(int i = tree[C].left; i <= tree[C].right; i++)
        used[i] = 1;
        return;
    }
    else if(tree[C].Cover == 0) return;
    if(tree[C].left == tree[C].right) return;
    down(C);
    query(L(C));
    query(R(C));
}
void solve(int l, int r, char lc, char rc, char op)
{
    int ll = 2 * l, rr = 2 * r;
    if(lc == '(') ll++;
    if(rc == ')') rr--;
    if(ll > rr)
    {
        if(op == 'C' || op == 'I')
        tree[1].Cover = tree[1].Xor = 0;
    }
    else update(ll, rr, 1, op);
}
int main()
{
    char str[5], lc, rc;
    int l, r;
    make_tree(0, MAXN, 1);
    while(scanf("%s %c%d,%d%c", str, &lc, &l, &r, &rc) != EOF)
    {
        solve(l, r, lc, rc, str[0]);
    }
    query(1);
    int flag = 0;
    int s = -1, e;

    for(int i = 0; i <= MAXN; i++)
    {
        if(used[i])
        {
            if(s == -1) s = i;
            e = i;
        }
        else
        {
            if(s != -1)
            {
                if(flag) printf(" ");
                flag = 1;
                lc = '[', rc = ')';
                if(s&1) lc = '(';
                if(!(e&1)) rc = ']';
                printf("%c%d,%d%c", lc, s>>1, (e+1)>>1, rc);
                s = -1;
            }
        }
    }
    if (!flag) printf("empty set");
    printf("\n");
    return 0;
}


你可能感兴趣的:(POJ 3225 Help with Intervals 线段树)