zoukankan      html  css  js  c++  java
  • poj 3225 线段树+位运算

    略复杂的一道题,首先要处理开闭区间问题,扩大两倍即可,注意输入最后要 ,初始化不能随便memset

    采用线段树,对线段区间进行0,1标记表示该区间是否包含在s内
    U T S ← S ∪ T 即将[l,r]标记为1
    I T S ← S ∩ T 即将-oo~l和r~+oo标记为0,因为是并集,所以并集后的集合s一定在[l,r]内,则在l,r内的集合被标记是什么状态就是什么状态(表示是否属于s),[l,r]外的集合不属于s所以标记为0
    D T S ← S - T  即将[l,r]标记为0,则在[l,r]内被s包含的集合也会标记为0表示不再属于s
    C T S ← T - S  即先将-oo~l,r~+oo标记为0,这部分不属于[l,r]则一定不属于s,然后将[l,r]的标记0/1互换,因为属于s的不再属于s,不属于s的将属于s
    S T S ← S ⊕ T  即属于s的不变,[l,r]中不属于s的(区间)0标记为1,属于s的(区间)1标记为0,所以[l,r]的标记0/1互换

    最后对区间l,r标记时标记将l*2,r*2标记,如果是闭区间则对l*2+1,或r*2-1进行标记,则输出的时候只需判断奇偶就能判断开闭区间
    是否覆盖0,1是否转换0,1的0,1转换都可以用异或去转换
    Sample Input
    U [1,5]
    D [3,3]
    S [2,4]
    C (1,5)
    I (2,3]
    Sample Output
    (2,3)

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<queue>
      7 #define lson l,m,rt<<1
      8 #define rson m+1,r,rt<<1|1
      9 using namespace std;
     10 const int maxn=131072;
     11 int tot=0;
     12 int n,m,t;
     13 int Xor[maxn<<2],cov[maxn<<2];   //异或标记,覆盖标记
     14 int hash[maxn<<2];
     15 void XXor(int rt)
     16 {
     17     if(cov[rt]!=-1) cov[rt]^=1;     //说明该区域有值存在
     18     else Xor[rt]^=1;
     19 }
     20 void pushdown(int rt)
     21 {
     22     if(cov[rt]!=-1)
     23     {
     24         cov[rt<<1]=cov[rt<<1|1]=cov[rt];
     25         Xor[rt<<1]=Xor[rt<<1|1]=0;
     26         cov[rt]=-1;
     27     }
     28     if(Xor[rt])
     29     {
     30         XXor(rt<<1);
     31         XXor(rt<<1|1);
     32         Xor[rt]=0;
     33     }
     34 }
     35 void update(char op,int L,int R,int l,int r,int rt)
     36 {
     37     if(l>=L&&r<=R)
     38     {
     39 
     40         if(op=='U') cov[rt]=1,Xor[rt]=0;
     41         else if(op=='D')    cov[rt]=Xor[rt]=0;
     42         else if(op=='C'||op=='S')   XXor(rt);
     43         return;
     44     }
     45     pushdown(rt);
     46     int m=(l+r)>>1;
     47     if(L<=m) update(op,L,R,lson);
     48     else if(op=='I'||op=='C')   cov[rt<<1]=Xor[rt<<1]=0;
     49     if(m<R) update(op,L,R,rson);
     50     else if(op=='I'||op=='C')   cov[rt<<1|1]=Xor[rt<<1|1]=0;
     51 }
     52 void query(int l,int r,int rt)
     53 {
     54     if(cov[rt]==1)
     55     {
     56         for(int i=l;i<=r;i++)   hash[i]=1;
     57         return;
     58     }
     59     else if(cov[rt]==0) return;
     60     if(l==r)    return;
     61     pushdown(rt);
     62     int m=(r+l)>>1;
     63     query(lson);
     64     query(rson);
     65 }
     66 int main()
     67 {
     68     int i,j,k;
     69     //freopen("1.in","r",stdin);
     70     char l,r,op;
     71     int a,b;
     72     while(scanf("%c %c%d,%d%c
    ",&op,&l,&a,&b,&r)!=EOF)
     73     {
     74         a<<=1,b<<=1;    //区间扩大一倍,解决开闭区间问题
     75         //printf("%d %d
    ",a,b);
     76         if(l=='(')  a++;
     77         if(r==')')  b--;
     78         if(a>b)         //说明a和b的值相等
     79         {
     80             if(op=='C'||op=='I')    cov[1]=Xor[1]=0,printf("");    //整个区间为0
     81         }
     82         else    update(op,a,b,0,maxn,1);
     83     }
     84     k=0;
     85     query(0,maxn,1);    //此时区间内的有效区域值为1
     86     int s=-1,e;    //判断左右区间位置
     87 
     88     for(i=0;i<=maxn;i++)
     89     {
     90         if(hash[i]) //该区域被覆盖
     91         {
     92             if(s==-1)   s=i;
     93             e=i;
     94         }
     95         else
     96         {
     97             if(s!=-1)    //说明存在一个完整区间
     98             {
     99                 if(k++) printf(" ");
    100                 printf("%c%d,%d%c",s&1?'(':'[',s>>1,(e+1)>>1,e&1?')':']');    //&运算用来判断奇偶,偶数的话二进制末位为0,and1得0,说明为闭区间
    101                 s=-1;
    102             }
    103         }
    104     }
    105     if(k==0)    printf("empty set");
    106     puts("");
    107     return 0;
    108 }
  • 相关阅读:
    Kafka调试入门(一)
    java笔记十五——多线程
    java笔记十四——初始集合源码
    java笔记十二——集合总结
    java笔记十一——异常
    java笔记十——大数类和日期类
    java笔记九——Object类与String类
    java笔记八——面向对象(三)
    java笔记七——面向对象(二)
    java笔记六——面向对象(一)
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4283369.html
Copyright © 2011-2022 走看看