zoukankan      html  css  js  c++  java
  • 宏大的区间

    【问题描述】
    小洪喜欢区间,他有一个宏大的区间游戏。
    小洪有一个集合S(初始为空),然后,小洪会依次对这个区间做一些操作,操作分为5种,5种操作以及集合之间的运算规则如下:
     
     
    wangy是小洪的粉丝,他想知道经过这些操作后的最终集合S。但他实在是太弱了,于是他找到了你,请你帮他解决这个问题。
     
    【输入格式】
    输入共m行,每行描述一个操作。
    每行的格式为O T,用一个空格隔开。O表示运算的种类,T为一个区间。区间用(a,b), (a,b], [a,b), [a,b]表示。
    保证输入数据中没有多余的空格。
     
    【输出格式】
    输出一行若干个用空格分开的区间,描述最终的集合S。你需要保证你输出的所有区间交集为空,并集为最终的S,并且你需要将它们按左端点从小到大排序。
    特别地,如果最终的集合S为空集,则输出一行”empty set”(不含引号)。
     
    【输入输出样例】
    interval1.in
    interval1.out
    U [1,5]
    D [3,3]
    S [2,4]
    C (1,5)
    I (2,3]
    U [4,6)
     
    (2,3) [4,6)
    interval2.in
    interval2.out
    S [3,5]
    S [3,5]
     
    empty set
     
    【数据规模】
    测试点编号
    m
    a,b
    备注
    1-3
    n≤100
    a,b≤255
     
    4-6
    所有区间为闭区间
    7-8
    n≤10001
    a,b≤65535
    9-12
    n≤40000
    13-15
    n≤10001
     
    16-19
    n≤40000
     
    20-25
    n≤200000
    a,b≤262143
     
    对于所有的数据,保证m>0,0≤a≤b。保证输入数据中的所有区间均不为空。
     
    考虑维护一棵权值线段树,中括号和小括号不好处理。
    我们将值域*2,那么小括号对应奇数,中括号对应偶数。
    线段树要支持区间赋值和区间取反的操作,注意空格输出空格。
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define lim 524287
     4 #define M 1500010
     5 int q[M];
     6 inline void Do(int o) {
     7     if(q[o] == 1 || q[o] == -1) {
     8         q[2 * o] = q[2 * o + 1] = q[o];
     9     }
    10     if(q[o] == 2) {
    11         q[2 * o] = -q[2 * o];
    12         q[2 * o + 1] = -q[2 * o + 1];
    13     }
    14     q[o] = -2;
    15 }
    16 inline void Add(int l, int r, int o, int x, int y, int z) {
    17     if(x <= l && r <= y) {
    18         q[o] = z;
    19         return;
    20     }
    21     int mid = (l + r) / 2;
    22     Do(o);
    23     if(x <= mid) Add(l, mid, 2 * o, x, y, z);
    24     if(y > mid) Add(mid + 1, r, 2 * o + 1, x, y, z);
    25 }
    26 inline void rev(int l, int r, int o, int x, int y) {
    27     if(x <= l && r <= y) {
    28         q[o] = -q[o];
    29         return;
    30     }
    31     int mid = (l + r) / 2;
    32     Do(o);
    33     if(x <= mid) rev(l, mid, 2 * o, x, y);
    34     if(y > mid) rev(mid + 1, r, 2 * o + 1, x, y);
    35 }
    36 inline void pd(int l, int r, int o) {
    37     if(l == r) return;
    38     int mid = (l + r) / 2;
    39     Do(o);
    40     pd(l, mid, 2 * o);
    41     pd(mid + 1, r, 2 * o + 1);
    42 }
    43 int main() {
    44     char s[10];
    45     memset(q, -1, sizeof(q));
    46     while(scanf("%s", s) != EOF) {
    47         char A, B;
    48         int l, r;
    49         A = getchar();
    50         while(A != '(' && A != '[') A = getchar();
    51         scanf("%d,%d", &l, &r);
    52         B = getchar();
    53         while(B != ')' && B != ']') B = getchar();
    54         l = l * 2 + (A == '(');
    55         r = r * 2 - (B == ')');
    56         if(s[0] == 'U') {
    57             Add(0, lim, 1, l, r, 1);
    58         }
    59         else if(s[0] == 'I') {
    60             if(l) Add(0, lim, 1, 0, l - 1, -1);
    61             Add(0, lim, 1, r + 1, lim, -1);
    62         }
    63         else if(s[0] == 'D') {
    64             Add(0, lim, 1, l, r, -1);
    65         }
    66         else if(s[0] == 'C') {
    67             if(l) Add(0, lim, 1, 0, l - 1, -1);
    68             Add(0, lim, 1, r + 1, lim, -1);
    69             rev(0, lim, 1, l, r);
    70         }
    71         else {
    72             rev(0, lim, 1, l, r);
    73         }
    74     }
    75     pd(0, lim, 1);
    76     q[lim] = -1;
    77     bool flag = false;
    78     for(int i = 0; i <= lim; ++ i) {
    79         if(q[lim + i] == -1 && q[i + lim + 1] == 1) {
    80             if(flag) printf(" ");
    81             if(i & 1) printf("(");
    82             else printf("[");
    83             printf("%d,", i / 2);
    84             flag = true;
    85         }
    86         if(q[lim + i] == 1 && q[i + lim + 1] == -1) {
    87             printf("%d", i / 2);
    88             if(i & 1) printf("]");
    89             else printf(")");
    90         }
    91     }
    92     if(!flag) puts("empty set");
    93 }
  • 相关阅读:
    初级程序员面试不靠谱指南(三)
    [细节决定B度]之回首一瞥cout<<"Hello,world"<<endl;
    20110310日记wmh
    SliverLight 控件属性的赋值方式
    20110309wmh日记
    20110308wmh日记
    20110307wmh日记
    STOAdiary20110314完成的任务
    20110313wmh日记
    20110311wmh日记
  • 原文地址:https://www.cnblogs.com/iamqzh233/p/9458136.html
Copyright © 2011-2022 走看看