• 【线段树】POJ3225-Help with Intervals


    ---恢复内容开始---

    【题目大意】

    (直接引用ACM神犇概括,貌似是notonlysucess?)

    U:把区间[l,r]覆盖成1
    I:把[-∞,l)(r,∞]覆盖成0
    D:把区间[l,r]覆盖成0
    C:把[-∞,l)(r,∞]覆盖成0 , 且[l,r]区间0/1互换
    S:[l,r]区间0/1互换

    【思路】

    由于涉及到开区间和闭区间,我们如此规定数组下表:

    下标      0      1      2      3      4      5……

    含义1   (1    1    (2      2    (3    3……

    含义2    /      /     1)     /      2)     /……


    cover表示区间覆盖,Xor表示区间取反。

    如果cover要直接覆盖的话,Xor的值就没有意义了,可以清为0;如果要区间取反的话,如果cover有值则将cover取反,否则就将Xor取反。注意一下边界……

    QuQ死磕了一个上午才搞定,后来才发现原来我忘记把freopen的语句删掉了!痛彻心扉,从此铭记,不再犯!

      1 /*模板来自于notonlysuccess*/
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cstring>
      6 #define lson l,m,rt<<1
      7 #define rson m+1,r,rt<<1|1
      8 using namespace std;
      9 const int MAXN=65536*2;
     10 int cover[MAXN<<2];//-1里面不确定,0覆盖0,1覆盖1 
     11 int Xor[MAXN<<2];//0表示区间取反过来,1表示区间不取反 
     12 int hash[MAXN+1];
     13 
     14 void Fxor(int rt)//对rt进行01对调 
     15 {
     16     if (cover[rt]!=-1) 
     17     {
     18         cover[rt]^=1;
     19     }
     20     else Xor[rt]^=1;
     21 }
     22 
     23 
     24 void pushdown(int rt)
     25 {
     26     if (cover[rt]!=-1)
     27     {
     28         cover[rt<<1]=cover[rt<<1|1]=cover[rt];
     29         Xor[rt<<1]=Xor[rt<<1|1]=0;
     30         cover[rt]=-1;//由于cover的值已经给两个孩子,此时将cover设为-1 
     31     }
     32     if (Xor[rt])
     33     {
     34         Fxor(rt<<1);
     35         Fxor(rt<<1|1);
     36         Xor[rt]=0;//由于已经将Xor的值给两个孩子,此时Xor清为0 
     37     }
     38 }
     39 
     40 void update(char op,int L,int R,int l,int r,int rt)
     41 {
     42     if (L<=l && r<=R)
     43     {
     44         if (op=='U')
     45         {
     46             cover[rt]=1;
     47             Xor[rt]=0;
     48         }
     49         else if (op=='D')
     50         {
     51             cover[rt]=0;
     52             Xor[rt]=0;
     53         }
     54         else if (op=='S'||op=='C')
     55             Fxor(rt);
     56         return;
     57     }
     58     pushdown(rt);
     59     int m=(l+r)>>1;
     60     if (m>=L) update(op,L,R,lson);
     61               else if  (op=='C'||op=='I') cover[rt<<1]=Xor[rt<<1]=0;
     62     if (m+1<=R) update(op,L,R,rson);
     63               else if  (op=='C'||op=='I')  cover[rt<<1|1]=Xor[rt<<1|1]=0;
     64 }
     65 
     66 void query(int l,int r,int rt)
     67 {
     68     if (cover[rt]==1)
     69     {
     70         for (int i=l;i<=r;i++) hash[i]=1;
     71         return;
     72     }else if (cover[rt]==0) return;//全部覆盖为0的时候直接退出 
     73     if (l==r) return;//说明已经走到了叶子节点 
     74     pushdown(rt);//凡是接下来要对孩子进行操作的,均要延迟更新 
     75     int m=(l+r)>>1;
     76     query(lson);
     77     query(rson);
     78 }
     79 
     80 void init()
     81 {
     82     char op,lo,ro;
     83     int l,r;
     84     Xor[1]=cover[1]=0;
     85     while (scanf("%c %c%d,%d%c",&op,&lo,&l,&r,&ro)!=EOF)
     86     {
     87         l<<=1;
     88         r<<=1;
     89         if (lo=='(') l++;
     90         if (ro==')') r--;
     91         if (l>r)
     92         {
     93             if (op=='C' || op=='I') cover[1]=Xor[1]=0;
     94         }
     95         else update(op,l,r,0,MAXN,1);
     96         getchar();
     97     }
     98 }
     99 
    100 void getans()
    101 {
    102     memset(hash,0,sizeof(hash));
    103     query(0,MAXN,1);
    104     int flag=0,s=-1,e=-1;
    105     for (int i=0;i<=MAXN;i++)
    106     {
    107         if (hash[i]==0 && s!=-1)
    108         {
    109             e=i-1;
    110             if (flag) cout<<' ';
    111             flag=1;
    112             printf("%c%d,%d%c", s&1?'(':'[', s>>1 , (e+1)>>1 , e&1?')':']');
    113             s=e=-1;
    114         }
    115         else
    116             if (hash[i]==1 && s==-1)
    117                 s=i;
    118     }
    119     if (!flag) cout<<"empty set"<<endl;
    120 }
    121 
    122 int main()
    123 {
    124     //freopen("POJ3225.in","r",stdin);
    125     init();
    126     getans();    
    127     return 0;
    128 }
  • 相关阅读:
    币圈惊现门罗币挖矿新家族「罗生门」
    5步告诉你QQ音乐的完美音质是怎么来的,播放器的秘密都在这里
    【云+社区极客说】新一代大数据技术:构建PB级云端数仓实践
    Android P的APP适配总结,让你快人一步
    C++11用于计算函数对象返回类型的统一方法
    C++11用于元编程的类别属性
    C++11多态函数对象包装器
    C++11包装引用
    C++11能用智能指针
    C++正则表达式
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5138847.html
Copyright © 2020-2023  润新知