• PKU 3225 Help with Intervals


    线段树经典入门题目;

    这道题有几点不同的地方:

    1. 维护的是集合,一个点或者一段区间都是一个集合,(2,3) 是一个集合,不能简单的用线段代替集合;

    2. 用离散的 01 值表示集合,对集合的运算需要转化为 01 区间的异或与赋值操作;

    3. 01 区间上进行异或和赋值,在 pushdown 的时候只能存在一个信息,一个线段要么被赋值,要么异或,不能既被赋值,同时进行异或(cover[]和xor[]不能同时有效);

    4. 结果要求输出运算结果(集合),在查询时,要做的不是查询到左端点、右端点,而是把被赋值的区间全部标记下来(O(n)),然后一次扫描完成输出,这道题卡了很长时间就是这里没想清楚(既然用了线段树,为什么还要O(n)呢?其实是只需要一次O(n),何必用线段树呢?);

    # include <stdio.h>
    # include <string.h>
    
    # define ls ((r)<<1)
    # define rs ((r)<<1 | 1)
    # define mid (((x)+(y))>>1)
    
    # define maxn (65535 * 2)
    
    char cc[maxn << 2], xx[maxn << 2],  hh[maxn+1];
    /*************************************************************/
    void XOR(int r)
    {
        if (cc[r] != -1) cc[r] ^= 1;
        else xx[r] ^= 1;
    }
    
    void pushdown(int x, int y, int r)
    {
        /* after pushdown cc[r]==-1 && xx[r]==0 */
        if (cc[r] != -1)
        {
            cc[ls] = cc[rs] = cc[r];
            xx[ls] = xx[rs] = 0;
            cc[r] = -1;
        }
        if (xx[r])
        {
            XOR(ls);
            XOR(rs);
            xx[r] = 0;
        }
    }
    
    void cover(int x, int y, int r, int s, int t, int val)
    {
        if (s<=x && y<=t)
        {
            cc[r] = val;
            xx[r] = 0;
            return ;
        }
        pushdown(x, y, r);
        if (s <= mid) cover(x, mid, ls, s, t, val);
        if (mid+1<=t) cover(mid+1, y, rs, s, t, val);
    }
    
    void xxor(int x, int y, int r, int s, int t)
    {
        if (s<=x && y<=t)
        {
            XOR(r);
            return ;
        }
        pushdown(x, y, r);
        if (s <= mid) xxor(x, mid, ls, s, t);
        if (mid+1<=t) xxor(mid+1, y, rs, s, t);
    }
    
    void query(int x, int y, int r)
    {
        int i;
        if (cc[r]!= -1)
        {
            if (cc[r] == 1) for (i = x; i <= y; ++i) hh[i] = 1;
            return ;
        }
        // if (x == y) return ;
        pushdown(x, y, r);
        query(x, mid, ls);
        query(mid+1, y, rs);
    }
    
    /*************************************************************/
    int main()
    {
        freopen("data.in", "r", stdin);
        freopen("data.out", "w", stdout);
        
        int s, t, i, first = 1;
        char op, lp, rp;
        
        while (~scanf("%c %c%d,%d%c\n", &op, &lp, &s, &t, &rp))
        {
            s <<= 1, t <<= 1;
            if (lp == '(') ++s;
            if (rp == ')') --t;
            if (s > t || (s==t && (s&0x1)))
            {
                if (op == 'I' || op == 'C') cc[1] = 0, xx[1] = 0;
                continue;
            }
            switch(op)
            {
                case 'U': cover(0, maxn, 1, s, t, 1);break;
                case 'D': cover(0, maxn, 1, s, t, 0);break;
                case 'I': {
                              if (s>0)       cover(0, maxn, 1, 0, s-1, 0);
                              if (t<maxn) cover(0, maxn, 1, t+1, maxn, 0);
                              break;
                          }
                 case 'C': {
                              if (s>0)    cover(0, maxn, 1, 0, s-1, 0);
                              if (t<maxn) cover(0, maxn, 1, t+1, maxn, 0);
                              xxor(0, maxn, 1, s, t);
                              break;
                          }          
                 case 'S': xxor(0, maxn, 1, s, t);break;
            }
        }
        query(0, maxn, 1);
        for (i = 0; i <= maxn; ++i)
        {
            if (hh[i])
            {
                if (first) first = 0;
                else putchar(' ');
                printf("%c%d,", i&0x1 ? '(':'[', i>>1);
                while (hh[i]) ++i;
                printf("%d%c", i>>1, (i-1)&0x1 ? ')':']');
            }
        }
        if (first) puts("empty set");
        else putchar('\n');
        
        return 0;
    } 

    代码写的丑,但是刚好跑到了notonlysuccess的前面,谢谢他的线段树专辑

  • 相关阅读:
    HTTP本地代理服务器遇到的问题
    SMTP协议(Python实现)
    MOS_Chapter2_Process And Thread
    数据库系统概念Chapter2关系模型
    数据库系统概念 Chapter1介绍
    数据库系统概念第六版 答案
    python之sys.argv[1] IndexError: list index out of range
    计算机网络自顶向下之应用层套接字编程作业Web服务器
    罗技G302按一下效果是按两下
    第二部分1.3遍历dom
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2651516.html
Copyright © 2020-2023  润新知