集合

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 }
原文地址:https://www.cnblogs.com/lightning34/p/4437807.html