• (中等) 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 time intervals, which have confused him a lot. Now he badly needs your help.

      In discrete mathematics, you have studied several basic set operations, namely union, intersection, relative complementation and symmetric difference, which naturally apply to the specialization of sets as intervals.. For your quick reference they are summarized in the table below:

    OperationNotation

    Definition

    Union A ∪ B {x : x ∈ A or x ∈ B}
    Intersection A ∩ B {x : x ∈ A and x ∈ B}
    Relative complementation A − B {x : x ∈ A but x ∉ B}
    Symmetric difference A ⊕ B (A − B) ∪ (B − A)

      Ikki has abstracted the interval operations emerging from his job as a tiny programming language. He wants you to implement an interpreter for him. The language maintains a set S, which starts out empty and is modified as specified by the following commands:

    CommandSemantics
    U T S ← S ∪ T
    I T S ← S ∩ T
    D T S ← S − T
    C T S ← T − S
    S T S ← S ⊕ T
      
      题目大致就是说对一个线段进行操作,然后问集合。
      首先要处理的是开区间和闭区间的表示,把所有数乘以2,开的话+1或-1(根据在左边还是右边而定)。
      然后就是集合的操作,并集的话直接覆盖为1,交集的话T的补集覆盖为0,D得话T覆盖为0,C的话先把T的补集覆盖为0,然后T区间取反,S的话T区间取反就好。
      有两个操作,所以维护两个操作,覆盖和取反。
      这里要注意,取反之后覆盖的话要把取反标记为0。
      另外,覆盖的话可以用-1为没有覆盖过,0为覆盖0,1为覆盖1,。
      也可以用0为没覆盖过,1为覆盖1,然后覆盖0的操作等价于覆盖1,然后取反。(我就是这样做的。)
     
    代码如下:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define lson L,M,po*2
    #define rson M+1,R,po*2+1
    
    using namespace std;
    
    const int N=65535*2;
    
    bool COL[140000*4]={0};
    bool XOR[140000*4]={0};
    bool vis[140000]={0};
    bool have=0;
    
    void pushDown(int po)
    {
        if(COL[po])
        {
            COL[po*2]=COL[po*2+1]=COL[po];
            COL[po]=0;
            XOR[po*2]=XOR[po*2+1]=0;            //  don't forget!!!
        }
    
        if(XOR[po])
        {
            XOR[po*2]=!XOR[po*2];
            XOR[po*2+1]=!XOR[po*2+1];
            XOR[po]=0;
        }
    }
    
    void updateC(int ul,int ur,bool type,int L,int R,int po)
    {
        if(ul>ur)
            return;
    
        if(ul<=L&&ur>=R)
        {
            XOR[po]=0;
            COL[po]=type;
    
            return;
        }
    
        pushDown(po);
    
        int M=(L+R)/2;
    
        if(ul<=M)
            updateC(ul,ur,type,lson);
        if(ur>M)
            updateC(ul,ur,type,rson);
    }
    
    void updateX(int ul,int ur,int L,int R,int po)
    {
        if(ul>ur)
            return;
    
        if(ul<=L&&ur>=R)
        {
            XOR[po]=!XOR[po];
    
            return;
        }
    
        pushDown(po);
    
        int M=(L+R)/2;
    
        if(ul<=M)
            updateX(ul,ur,lson);
        if(ur>M)
            updateX(ul,ur,rson);
    }
    
    void query(int L,int R,int po)
    {
        if(L==R)
        {
            vis[L]=COL[po]^XOR[po];
    
            if(vis[L])
                have=1;
    
            return;
        }
    
        pushDown(po);
    
        int M=(L+R)/2;
    
        query(lson);
        query(rson);
    }
    
    int main()
    {
        char C;
        char t1,t2;
        int a,b;
        int x,y;
    
        while(cin>>C)
        {
            scanf(" %c%d,",&t1,&a);
            scanf("%d%c",&b,&t2);
    
            a*=2;
            b*=2;
    
            if(t1=='(')
                ++a;
            if(t2==')')
                --b;
    
            switch(C)
            {
            case 'U':
                updateC(a,b,1,0,N,1);
                break;
    
            case 'I':
                updateC(0,a-1,1,0,N,1);
                updateX(0,a-1,0,N,1);
                updateC(b+1,N,1,0,N,1);
                updateX(b+1,N,0,N,1);
                break;
    
            case 'D':
                updateC(a,b,1,0,N,1);
                updateX(a,b,0,N,1);
                break;
    
            case 'C':
                updateC(0,a-1,1,0,N,1);
                updateX(0,a-1,0,N,1);
                updateC(b+1,N,1,0,N,1);
                updateX(b+1,N,0,N,1);
                updateX(a,b,0,N,1);
                break;
    
            case 'S':
                updateX(a,b,0,N,1);
                break;
    
            }
        }
    
        query(0,N,1);
    
        if(!have)
        {
            printf("empty set
    ");
            return 0;
        }
    
        bool has=0;
        for(int i=0;i<=N+1;++i)
        {
            if(vis[i])
            {
                if(!has)
                {
                    has=1;
                    if(i%2)
                        printf("(%d,",(i-1)/2);
                    else
                        printf("[%d,",i/2);
                }
            }
            else
            {
                if(has)
                {
                    has=0;
                    if((i-1)%2)
                        printf("%d) ",i/2);
                    else
                        printf("%d] ",(i-1)/2);
                }
            }
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    树莓派aria2 init文档
    树莓派aria2 init文档
    HDU 6000 Wash【优先队列优化贪心】【最大值+最小值】
    HDU 6000 Wash【优先队列优化贪心】【最大值+最小值】
    HDU 3264||POJ 3831 Open-air shopping malls【计算机几何】【圆相交面积模板】
    HDU 3264||POJ 3831 Open-air shopping malls【计算机几何】【圆相交面积模板】
    HDU 6178 Monkeys【dfs】【输入外挂模板】
    HDU 6178 Monkeys【dfs】【输入外挂模板】
    HDU 6181 Two Paths【次短路】【模板题】
    返回一个二维整数数组中最大子数组的和
  • 原文地址:https://www.cnblogs.com/whywhy/p/4194727.html
Copyright © 2020-2023  润新知