• 3226. [SDOI2008]校门外的区间【线段树】


    Description

     
      受校门外的树这道经典问题的启发,A君根据基本的离散数学的知识,抽象出5种运算维护集合S(S初始为空)并最终输出S。现在,请你完成这道校门外的树之难度增强版——校门外的区间。
     
      5种运算如下:
    S∪T
    S∩T
    S-T
    T-S
    S⊕T
     
      基本集合运算如下:
    {x : xÎA or xÎB}
    {x : xÎA and xÎB}
    {x : xÎA and xÏB}
    (A-B)∪(B-A)
     

    Input

      输入共M行。
      每行的格式为X T,用一个空格隔开,X表示运算的种类,T为一个区间(区间用(a,b), (a,b], [a,b), [a,b]表示)。
     

    Output

     
      共一行,即集合S,每个区间后面带一个空格。若S为空则输出"empty set"。
     

    Sample Input

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

    Sample Output

    (2,3)

    HINT

    对于 100% 的数据,0≤a≤b≤65535,1≤M≤70000

    0代表没有,1代表有
    U并:T区间*0 +1
    I交:T区间外*0
    D减:T区间*0
    C(T-S):T外面的*0,然后T*-1  +1
    S:T区间-1 *-1
    然后每个点拆成三个点,用来处理开区间和闭区间

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #define LL long long
      5 #define N (300000)
      6 using namespace std;
      7 struct emm
      8 {
      9     LL val,add,mul;
     10 }Segt[N*4];
     11 LL opt,x,y,n=300000;
     12 char st[100];
     13 
     14 void Pushdown(LL node,LL l,LL r)
     15 {
     16     if (Segt[node].mul!=1)
     17     {
     18         Segt[node*2].mul*=Segt[node].mul;
     19         Segt[node*2+1].mul*=Segt[node].mul;
     20         Segt[node*2].add*=Segt[node].mul;
     21         Segt[node*2+1].add*=Segt[node].mul;
     22         
     23         Segt[node*2].val*=Segt[node].mul;
     24         Segt[node*2+1].val*=Segt[node].mul;
     25         Segt[node].mul=1;
     26     }
     27     if (Segt[node].add!=0)
     28     {
     29         Segt[node*2].add+=Segt[node].add;
     30         Segt[node*2+1].add+=Segt[node].add;
     31         LL mid=(l+r)/2;
     32         Segt[node*2].val+=(mid-l+1)*Segt[node].add;
     33         Segt[node*2+1].val+=(r-mid)*Segt[node].add;
     34         Segt[node].add=0;
     35     }
     36 }
     37 
     38 LL Query(LL node,LL l,LL r,LL l1,LL r1)
     39 {
     40     if (l>r1 || r<l1) return 0;
     41     if (l1<=l && r<=r1)
     42         return Segt[node].val;
     43     Pushdown(node,l,r);
     44     LL mid=(l+r)/2;
     45     return Query(node*2,l,mid,l1,r1)+Query(node*2+1,mid+1,r,l1,r1);
     46 }
     47 
     48 void Add(LL node,LL l,LL r,LL l1,LL r1,LL k)
     49 {
     50     if (l>r1 || r<l1) return;
     51     if (l1<=l && r<=r1)
     52     {
     53         Segt[node].val+=(r-l+1)*k;
     54         Segt[node].add+=k;
     55         return;
     56     }
     57     Pushdown(node,l,r);
     58     LL mid=(l+r)/2;
     59     Add(node*2,l,mid,l1,r1,k);
     60     Add(node*2+1,mid+1,r,l1,r1,k);
     61     Segt[node].val=Segt[node*2].val+Segt[node*2+1].val;
     62 }
     63 
     64 void Mul(LL node,LL l,LL r,LL l1,LL r1,LL k)
     65 {
     66     if (l>r1 || r<l1) return;
     67     if (l1<=l && r<=r1)
     68     {
     69         Segt[node].mul*=k;
     70         Segt[node].add*=k;
     71         Segt[node].val*=k;
     72         return;
     73     }
     74     Pushdown(node,l,r);
     75     LL mid=(l+r)/2;
     76     Mul(node*2,l,mid,l1,r1,k);
     77     Mul(node*2+1,mid+1,r,l1,r1,k);
     78     Segt[node].val=Segt[node*2].val+Segt[node*2+1].val;
     79 }
     80 
     81 void Init()
     82 {
     83     if (st[0]=='U') opt=1;
     84     if (st[0]=='I') opt=2;
     85     if (st[0]=='D') opt=3;
     86     if (st[0]=='C') opt=4;
     87     if (st[0]=='S') opt=5;
     88     cin>>st;
     89     x=0,y=0;
     90     LL s=1;
     91     while (1)
     92     {
     93         if (st[s]==',') break;
     94         x=x*10+st[s]-'0'; s++;
     95     }
     96     for (LL i=s+1;i<=strlen(st)-2;++i)
     97         y=y*10+st[i]-'0';
     98     x=x*3+2;
     99     if (st[0]=='(') x++;
    100     y=y*3+2;
    101     if (st[strlen(st)-1]==')') y--;
    102 }
    103 
    104 void print()
    105 {
    106     bool flag=false,refun=false;
    107     LL i=1;
    108     while (i<=n)
    109     {
    110         if (!flag && (i-1)%3+1>=2 && Query(1,1,n,i,i)>0)
    111         {
    112             flag=true;refun=true;
    113             if ((i-1)%3+1==2) cout<<'['; else cout <<'(';
    114             cout<<(i-1)/3<<',';
    115         }
    116         if (flag && Query(1,1,n,i,i)<=0)
    117         {
    118             flag=false;refun=true;
    119             cout<<(i-2)/3;
    120             if ((i-2)%3+1>=2) cout<<"] "; else cout <<") ";
    121         }
    122         ++i;
    123     }
    124     if (!refun) cout<<"empty set";
    125 }
    126 
    127 int main()
    128 {
    129     for (LL i=1;i<=n*4;++i) Segt[i].mul=1;
    130     LL i=0;
    131     while (cin>>st)
    132     {
    133         Init();
    134         i++;
    135         if (opt==1) Mul(1,1,n,x,y,0),Add(1,1,n,x,y,1);
    136         if (opt==2) Mul(1,1,n,1,x-1,0),Mul(1,1,n,y+1,n,0);
    137         if (opt==3) Mul(1,1,n,x,y,0);
    138         if (opt==4) Mul(1,1,n,1,x-1,0),Mul(1,1,n,y+1,n,0),Mul(1,1,n,x,y,-1),Add(1,1,n,x,y,1);
    139         if (opt==5) Add(1,1,n,x,y,-1),Mul(1,1,n,x,y,-1);     
    140     }
    141     print();
    142 }
  • 相关阅读:
    软件工程之旅开始啦
    c# async,await, 委托函数
    mysql 访问不是本地数据库,给用户刷新了权限没有作用
    c# WndProc事件 消息类型
    sql not in 优化问题
    c# dataGridView 表头格式设置不管用
    sql 更新多条记录
    mysql 插多行数据
    win7 64bit+vs2010 操作注册表
    bat脚本命令
  • 原文地址:https://www.cnblogs.com/refun/p/8680744.html
Copyright © 2020-2023  润新知