• 集合


    Description

    对于实数集合,定义以下操作:

             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 not x∈B}

             Symmetric difference :A⊕B = (A - B) ∪(B - A)

    令当前的主集合为S,给定集合T ,以下是集合处理的简单表示:

    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

    假设S一开始为空集,对于给定指令,求出最终的S 集合。

    Input Format

    若干行,每行一条指令,格式如上。

    T集合的模式为(a,b),(a,b],[a,b)或[a,b]

    a b均为整数,以文件结束结尾。

    数据保证a<=b,其中集合为[a,b]且a=b时请视为该集合里只含一个元素。

    Output Format

    在一行中用尽量少的区间描述集合S,格式同输入格式,按左端点从小到大输出,每个区间后跟一个空格,详见样例。

    保证最终S不为空集

    Sample Input

    U [1,5]
    D [3,3]
    S [2,4]
    C (1,5)
    I (2,3]
    U (4,5]
    

    Sample Output

    (2,3) (4,5]

    Hint

    对于40%的数据,不超过1000条指令

    对于100%的数据,不超过65536条指令,0<=a<=b<65536

    保证指令及答案合法。

    分析:

      实际上就是一个可以维护区间内1的个数的线段树。

      这几种操作都可以分解成两种基本操作:区间赋值和区间取反。

      S∪T : 将区间T赋值为1

      S∩T : 将区间0~T.left和区间T.right~INF赋值为0

      S - T : 将区间T赋值为0

      T - S : 将区间0~T.left和区间T.right~INF赋值为0,对区间T取反

      S⊕T : 对区间T取反

      开闭区间可以看成0.5来维护,把数值都乘以2就好了。

      关键在于处理好两个lazy-tag的关系。

    代码:

      1 #include <cstdio>
      2 #include <cstring>
      3 
      4 int n, q, i, al, ar, ak, ai, len;
      5 int s[800000], lz[800000], rt[800000], x1, x2, x[3], p;
      6 char act[10], read[100];
      7 int ql, qr;
      8 
      9 #define MID (l + r >> 1)
     10 #define up(o) (s[o] = s[o << 1] + s[o << 1 | 1])
     11 
     12 void build (int x, int l, int r)
     13 {
     14     if (l != r) build (x << 1, l, MID), build (x << 1 | 1, MID + 1, r);
     15 }
     16 
     17 void down (int x, int l, int r)
     18 {
     19     if (lz[x] != -1)
     20     {
     21         s[x << 1] = (MID - l + 1) * lz[x];
     22         lz[x << 1] = lz[x], rt[x << 1] = 0;
     23         s[x << 1 | 1] = (r - MID) * lz[x];
     24         lz[x << 1 | 1] = lz[x], rt[x << 1 | 1] = 0;
     25         lz[x] = -1;
     26     }
     27     if (rt[x])
     28     {
     29         rt[x << 1] = !rt[x << 1];
     30         s[x << 1] = MID - l + 1 - s[x << 1];
     31         rt[x << 1 | 1] = !rt[x << 1 | 1];
     32         s[x << 1 | 1] = r - MID - s[x << 1 | 1];
     33         rt[x] = 0;
     34     }
     35 }
     36 
     37 void modify (int x, int l, int r)
     38 {
     39     if (l > ar || r < al) return;
     40     if (l >= al && r <= ar)
     41     {
     42         s[x] = (r - l + 1) * ak;
     43         lz[x] = ak; rt[x] = 0; return;
     44     }
     45     down (x, l, r);
     46     if (al <= MID) modify (x << 1, l, MID);
     47     if (ar > MID) modify (x << 1 | 1, MID + 1, r);
     48     l != r ? up (x) : 0;
     49 }
     50 
     51 void rotate (int x, int l, int r)
     52 {
     53     if (l >= al && r <= ar)
     54     {
     55         s[x] = r - l + 1 - s[x];
     56         rt[x] = !rt[x]; return;
     57     }
     58     down (x, l, r);
     59     if (al <= MID) rotate (x << 1, l, MID);
     60     if (ar > MID) rotate (x << 1 | 1, MID + 1, r);
     61     l != r ? up (x) : 0;
     62 }
     63 
     64 void search (int x, int l, int r)
     65 {
     66     if (l == r)
     67     {
     68         if (s[x])
     69         {
     70             if (l > qr) ql = l;
     71             qr = l + 1;
     72         }else
     73         {
     74             if (l == qr)
     75             {
     76                 qr--;
     77                 printf (ql % 2 ? "(" : "[");
     78                 printf ("%d,%d", ql / 2, qr / 2 + qr % 2);
     79                 printf (qr % 2 ? ") " : "] ");
     80             }
     81         }
     82     }else
     83     {
     84         down (x, l, r);
     85         search (x << 1, l, MID);
     86         search (x << 1 | 1, MID + 1, r);
     87     }
     88 }
     89 
     90 int main ()
     91 {
     92     build (1, 0, 150000);
     93     while (~scanf ("%s", act))
     94     {
     95         scanf ("%s", read);
     96         len = strlen (read);
     97         i = 1, p = 0;
     98         x[0] = x[1] = 0;
     99         while (i < len)
    100         {
    101             if (read[i] >= '0' && read[i] <= '9')
    102                 x[p] = x[p] * 10 + read[i] - '0';
    103             else p++;
    104             i++;
    105         }
    106         x1 = x[0] * 2 + (read[0] == '(');
    107         x2 = x[1] * 2 - (read[len - 1] == ')');
    108         switch (act[0])
    109         {
    110             case 'U':
    111                 al = x1, ar = x2, ak = 1;
    112                 if (al <= ar) modify (1, 0, 150000);
    113             break;
    114             case 'I':
    115                 al = 0, ar = x1 - 1, ak = 0;
    116                 if (al <= ar) modify (1, 0, 150000);
    117                 al = x2 + 1, ar = 150000, ak = 0;
    118                 if (al <= ar) modify (1, 0, 150000);
    119             break;
    120             case 'D':
    121                 al = x1, ar = x2, ak = 0;
    122                 if (al <= ar) modify (1, 0, 150000);
    123             break;
    124             case 'C':
    125                 al = 0, ar = x1 - 1, ak = 0;
    126                 if (al <= ar) modify (1, 0, 150000);
    127                 al = x2 + 1, ar = 150000, ak = 0;
    128                 if (al <= ar) modify (1, 0, 150000);
    129                 al = x1, ar = x2;
    130                 if (al <= ar) rotate (1, 0, 150000);
    131             break;
    132             case 'S':
    133                 al = x1, ar = x2;
    134                 if (al <= ar) rotate (1, 0, 150000);
    135             break;
    136         }
    137     }
    138     ql = qr = -1;
    139     search (1, 0, 150000);
    140 }
  • 相关阅读:
    Python 冒泡排序
    编程规范之注释篇
    编程规范之变量命名篇
    安装Django
    字典&列表的拓展理解
    小球落地
    Python结合sql登陆案例
    面向对象:两手交换牌
    每日一题(一)
    Web应用之LAMP源码环境部署
  • 原文地址:https://www.cnblogs.com/lightning34/p/4437807.html
Copyright © 2020-2023  润新知