poj 3225 Help with Intervals(线段树)

题目链接:poj 3225 Help with Intervals

题目大意:模拟集合操作,输出最终的集合。

解题思路:线段树。

  • U l r:[l,r]区间置为1
  • I l r:[0,l),(r,maxn]置为0
  • D l r:[l,r]区间置为0
  • C l r:[0,l),(r,maxn]置为0,[l,r]区间取逆
  • S l r:[l,r]区间取逆。

然后基本水水的线段树,注意一下区间开和闭。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 65535 * 2;

#define lson(x) ((x)<<1)
#define rson(x) (((x)<<1)+1)

int lc[maxn * 4], rc[maxn * 4], set[maxn * 4], filp[maxn * 4];

inline void splay(int u) {
    filp[u] ^= 1;

    if (filp[u] && set[u] != -1) {
        filp[u] = 0;
        set[u] ^= 1;
    }
}

inline void maintain(int u, int v) {
    set[u] = v;
    filp[u] = 0;
}

inline void pushdown (int u) {
    if (set[u] != -1) {
        maintain(lson(u), set[u]);
        maintain(rson(u), set[u]);
        set[u] = -1;
    }

    if (filp[u]) {
        splay(lson(u));
        splay(rson(u));
        filp[u] = 0;
    }
}

void build (int u, int l, int r) {
    lc[u] = l;
    rc[u] = r;
    maintain(u, -1);

    if (l == r) {
        maintain(u, 0);
        return;
    }

    int mid = (l + r) / 2;
    build (lson(u), l, mid);
    build (rson(u), mid + 1, r);
}

void modify (int u, int l, int r, int v) {
    if (l > r) return;

    if (l <= lc[u] && rc[u] <= r) {
        maintain(u, v);
        return;
    }

    pushdown(u);
    int mid = (lc[u] + rc[u]) / 2;
    if (l <= mid)
        modify(lson(u), l, r, v);
    if (r > mid)
        modify(rson(u), l, r, v);
}

void change (int u, int l, int r) {
    if (l > r) return;

    if (l <= lc[u] && rc[u] <= r) {
        splay(u);
        return;
    }

    pushdown(u);
    int mid = (lc[u] + rc[u]) / 2;
    if (l <= mid)
        change(lson(u), l, r);
    if (r > mid)
        change(rson(u), l, r);
}

int query (int u, int x) {
    if (lc[u] == x && x == rc[u])
        return set[u];

    pushdown(u);
    int mid = (lc[u] + rc[u]) / 2;
    if (x <= mid)
        return query(lson(u), x);
    else
        return query(rson(u), x);
}

int L, R;
char op, LP, RP;

inline void put (int left, int right) {
    if (left&1)
        printf("(%d,", left/2);
    else
        printf("[%d,", left/2);

    if (right&1)
        printf("%d)", (right + 1) / 2);
    else
        printf("%d]", right / 2);
}

int main () {
    build (1, 0, maxn);

    while (~scanf("%c%*c%c%d,%d%c%*c", &op, &LP, &L, &R, &RP)) {
        L *= 2;
        R *= 2;
        if (LP == ‘(‘)
            L++;
        if (RP == ‘)‘)
            R--;

        if (op == ‘U‘) {
            modify(1, L, R, 1);
        } else if (op == ‘I‘) {
            modify(1, 0, L - 1, 0);
            modify(1, R + 1, maxn, 0);
        } else if (op == ‘D‘) {
            modify(1, L, R, 0);
        } else if (op == ‘C‘) {
            change(1, L, R);
            modify(1, 0, L - 1, 0);
            modify(1, R + 1, maxn, 0);
        } else if (op == ‘S‘)
            change(1, L, R);
    }

    bool flag = false;
    int c = 0, t;

    for (int i = 0; i <= maxn; i++) {
        int s = query(1, i);
        if (s && !flag) {
            t = i;
            flag = true;
        } else if (!s && flag) {
            if (c++)
                printf(" ");
            put(t, i-1);
            flag = false;
        }
    }

    if (c == 0)
        printf("empty set\n");
    else
        printf("\n");

    return 0;
}
时间: 2024-08-07 08:08:17

poj 3225 Help with Intervals(线段树)的相关文章

poj 3225 Help with Intervals(线段树,区间更新)

Help with Intervals Time Limit: 6000MS   Memory Limit: 131072K Total Submissions: 12474   Accepted: 3140 Case Time Limit: 2000MS Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on g

(中等) POJ 3225 Help with Intervals , 线段树+集合。

Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on graduation design, he is also engaged in an internship at LogLoader. Among his tasks, one is to write a module for manipulating ti

POJ 3225 Help with Intervals(线段树)

POJ 3225 Help with Intervals 题目链接 集合数字有的为1,没有为0,那么几种操作对应就是置为0或置为1或者翻转,这个随便推推就可以了,然后开闭区间的处理方式就是把区间扩大成两倍,偶数存点,奇数存线段即可 代码: #include <cstdio> #include <cstring> #define lson(x) ((x<<1)+1) #define rson(x) ((x<<1)+2) const int N = 65536

poj 3225 Help with Intervals

http://poj.org/problem?id=3225 题意:对集合进行交.并.差.异或四种操作,输出几步操作的之后的集合. U [a,b]  :可以将[a,b]全部置为1:  I [a,b] :可以将[a,b]之外的全部置为0:   S-[a,b] :将[a,b]全部置为0:  [a,b]-s  :将[a,b]之外的全部置为0,[a,b]取反.  I [a,b]  :将[a,b]取反. 然后用线段树维护区间. 1 #include <cstdio> 2 #include <cst

POJ - 3225 Help with Intervals (开闭区间)

Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on graduation design, he is also engaged in an internship at LogLoader. Among his tasks, one is to write a module for manipulating ti

POJ 2528 Mayor&#39;s posters (线段树区间更新+离散化)

题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值.由于l和r范围比较大,内存就不够了,所以就用离散化的技巧 比如将1 4化为1 2,范围缩小,但是不影响答案. 写了这题之后对区间更新的理解有点加深了,重点在覆盖的理解(更新左右两个孩子节点,然后值清空),还是要多做做题目. 1 #include <iostream> 2 #include <

POJ 2777 Count Color (线段树区间更新加查询)

Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem. There is a very long board with length L centimeter, L is a positive integer, so we can evenly d

poj 2777 Count Color(线段树区间修改)

题目链接:http://poj.org/problem?id=2777 题目意思:就是问你在询问的区间里有几种不同的颜色 思路:这题和一般的区间修改差不多,但是唯一不同的就是我们要怎么计算有种颜色,所以这时候我们就需要把延时标记赋予不同的意义,当某段区间有多种颜色时就赋值为-1,当为一种颜色时就把它赋值为这个颜色的号数.这儿我们要怎么统计询问区间不同的颜色数叻,为了不重复计算同一种颜色,那么我们就需要用一个数组来标记计算过的颜色,当我们下次遇到时就不需要再次计算了.... 代码核心处就在计数那儿

poj 3368 Frequent values(线段树解法)

题目链接:http://poj.org/problem?id=3368 题目大意:给你一段不下降的序列,求给定区间里出现次数最多的那个数字的次数. 思路:首先看到这题时,第一感觉线段树,但是仔细一看问题来啦,用线段数我怎么才能计算出某段区间里出现的那个数,因为出现最多的那个数可能不是在他它的左儿子上也不是在它的右儿子上,可能在当他们合并成一个区间时就出现啦,但是这儿我们需要注意的就是,题目给的是一段不下降的序列,那么突破口就出来啦,因为如果出现相同的数字,那么它们一定是连续的.所以我们只需要在普