码迷,mamicode.com
首页 > 其他好文 > 详细

【线段树】POJ3225-Help with Intervals

时间:2016-01-18 13:45:31      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:

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

【题目大意】

(直接引用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 }

【线段树】POJ3225-Help with Intervals

标签:

原文地址:http://www.cnblogs.com/iiyiyi/p/5138847.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!