poj 3225 Help with Intervals

http://poj.org/problem?id=3225

题意:对集合进行交、并、差、异或四种操作,输出几步操作的之后的集合。

U [a,b]  :可以将[a,b]全部置为1;  I [a,b] :可以将[a,b]之外的全部置为0;   S-[a,b] :将[a,b]全部置为0;  [a,b]-s  :将[a,b]之外的全部置为0,[a,b]取反。  I [a,b]  :将[a,b]取反。

然后用线段树维护区间。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include<cctype>
  4 #include <algorithm>
  5 #define maxn 132000
  6 using namespace std;
  7 const int N=6000000;
  8
  9 char str[100];
 10 bool visi[N];
 11 struct node
 12 {
 13     int l,r;
 14     int x;
 15     bool flag;
 16 }tree[N];
 17
 18 void build(int i,int l,int r)
 19 {
 20     tree[i].l=l;
 21     tree[i].r=r;
 22     tree[i].x=0;
 23     tree[i].flag=false;
 24     if(l==r) return ;
 25     int mid=(l+r)>>1;
 26     build(i<<1,l,mid);
 27     build(i<<1|1,mid+1,r);
 28 }
 29 void down(int i)
 30 {
 31     if(tree[i].l==tree[i].r)
 32     {
 33         if(tree[i].flag)
 34         {
 35             tree[i].x^=1;
 36             tree[i].flag=false;
 37         }
 38         return ;
 39     }
 40     if(tree[i].x!=-1)
 41     {
 42         if(tree[i].flag)
 43             tree[i].x^=1;
 44         tree[i<<1].x=tree[i<<1|1].x=tree[i].x;
 45         tree[i].x=-1;
 46         tree[i<<1].flag=tree[i<<1|1].flag=false;
 47         tree[i].flag=false;
 48     }
 49     if(tree[i].flag)
 50     {
 51         tree[i].flag=false;
 52         if(tree[i<<1].x!=-1)
 53             tree[i<<1].x^=1;
 54         else
 55             tree[i<<1].flag^=true;
 56         if(tree[i<<1|1].x!=-1)
 57            tree[i<<1|1].x^=1;
 58         else
 59             tree[i<<1|1].flag^=true;
 60     }
 61 }
 62 void deal(int i,int l,int r,int c)
 63 {
 64     if(l>r) return;
 65     if(tree[i].l==l&&tree[i].r==r)
 66     {
 67         if(c==0||c==1)
 68         {
 69             tree[i].x=c;
 70             tree[i].flag=false;
 71         }
 72         else if(tree[i].x!=-1)
 73         {
 74             tree[i].x^=1;
 75         }
 76         else
 77             tree[i].flag^=1;
 78         return ;
 79     }
 80     down(i);
 81     int mid=(tree[i].l+tree[i].r)>>1;
 82     if(r<=mid)
 83     {
 84         deal(i<<1,l,r,c);
 85     }
 86     else if(l>mid)
 87     {
 88         deal(i<<1|1,l,r,c);
 89     }
 90     else
 91     {
 92         deal(i<<1,l,mid,c);
 93         deal(i<<1|1,mid+1,r,c);
 94     }
 95 }
 96
 97 void search1(int i)
 98 {
 99     if(tree[i].x!=-1)
100     {
101         if(tree[i].x==1)
102         {
103             for(int j=tree[i].l; j<=tree[i].r; j++)
104                 visi[j]=true;
105         }
106         return ;
107     }
108     down(i);
109     search1(i<<1);
110     search1(i<<1|1);
111 }
112 int main()
113 {
114     build(1,0,maxn);
115     while(gets(str))
116     {
117         int k=strlen(str);
118         int x=0,y=0;
119         int i;
120         for(i=3; i<k; i++)
121         {
122             if(!isdigit(str[i])) break;
123             x=x*10+(str[i]-‘0‘);
124         }
125         int j;
126         for(j=i+1; j<k; j++)
127         {
128             if(!isdigit(str[j])) break;
129             y=y*10+(str[j]-‘0‘);
130         }
131         if(str[2]==‘[‘) x=x*2;
132         else x=x*2+1;
133         if(str[j]==‘]‘) y=y*2;
134         else y=y*2-1;
135         if(str[0]==‘U‘)
136         {
137             deal(1,x,y,1);
138         }
139         else if(str[0]==‘I‘)
140         {
141             deal(1,0,x-1,0);
142             deal(1,y+1,maxn,0);
143         }
144         else if(str[0]==‘D‘)
145         {
146             deal(1,x,y,0);
147         }
148         else if(str[0]==‘C‘)
149         {
150             deal(1,0,x-1,0);
151             deal(1,y+1,maxn,0);
152             deal(1,x,y,2);
153         }
154         else if(str[0]==‘S‘)
155         {
156             deal(1,x,y,2);
157         }
158     }
159     memset(visi,false,sizeof(visi));
160     search1(1);
161     bool flag=false;
162     for(int i=0; i<=maxn; i++)
163     {
164         if(!visi[i]) continue;
165         int xx=i;
166         while(visi[i]&&i<=maxn) i++;
167         int yy=(--i);
168         if(!flag) flag=true;
169         else printf(" ");
170         if(xx%2==0) printf("[%d,",xx/2);
171         else printf("(%d,",xx/2);
172         if(yy%2==0) printf("%d]",yy/2);
173         else printf("%d)",(yy+1)/2);
174     }
175     if(!flag) printf("empty set");
176     printf("\n");
177     return 0;
178 }

poj 3225 Help with Intervals,布布扣,bubuko.com

时间: 2024-08-07 16:37:43

poj 3225 Help with Intervals的相关文章

poj 3225 Help with Intervals(线段树)

题目链接:poj 3225 Help with Intervals 题目大意:模拟集合操作,输出最终的集合. 解题思路:线段树. U l r:[l,r]区间置为1 I l r:[0,l),(r,maxn]置为0 D l r:[l,r]区间置为0 C l r:[0,l),(r,maxn]置为0,[l,r]区间取逆 S l r:[l,r]区间取逆. 然后基本水水的线段树,注意一下区间开和闭. #include <cstdio> #include <cstring> #include &

POJ - 3225 Help with Intervals (开闭区间)

Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on graduation design, he is also engaged in an internship at LogLoader. Among his tasks, one is to write a module for manipulating ti

POJ 3225 Help with Intervals(线段树)

POJ 3225 Help with Intervals 题目链接 集合数字有的为1,没有为0,那么几种操作对应就是置为0或置为1或者翻转,这个随便推推就可以了,然后开闭区间的处理方式就是把区间扩大成两倍,偶数存点,奇数存线段即可 代码: #include <cstdio> #include <cstring> #define lson(x) ((x<<1)+1) #define rson(x) ((x<<1)+2) const int N = 65536

poj 3225 Help with Intervals(线段树,区间更新)

Help with Intervals Time Limit: 6000MS   Memory Limit: 131072K Total Submissions: 12474   Accepted: 3140 Case Time Limit: 2000MS Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on g

POJ - 3225 - Help with Intervals 【区间的并、交、差、对称差】

http://poj.org/problem?id=3225 两大难点: 1. 区间的集合操作: 2. 区间端点的开.闭的区分方式: 区间的端点x都要两种状态,要么包含x,要么不含x ——可见,每个数其实都要两个值来存储区间的开闭状态,我可以联想到每一个坐标乘以2! 即,对于区间左端点L, L*2代表:[L L*2+1代表:(L 而对于区间右端点R, R*2代表:R] R*2-1代表:R) 我们画一下草稿,就可以看出,上述原则实际上是: 经过计算后的数字k(比如,左闭端点L,计算后为k=L*2;

(中等) POJ 3225 Help with Intervals , 线段树+集合。

Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on graduation design, he is also engaged in an internship at LogLoader. Among his tasks, one is to write a module for manipulating ti

POJ 3225——Help with Intervals(线段树,成段替换+区间异或+hash)

Help with Intervals Time Limit: 6000MS   Memory Limit: 131072K Total Submissions: 10444   Accepted: 2551 Case Time Limit: 2000MS Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on g

poj 3225 区间(区间的交并补操作)

http://poj.org/problem?id=3225 一道题又做了一天..这道题对我来说起初有N多难点. 1:区间的开闭如何解决.. 2:怎样把区间的交并补.对称差转化为对线段树的操作. 后来与实验室的同学讨论了后解决了前面两个问题. 对于区间的开闭,可以将区间放大一倍,偶数点表示端点,奇数点表示区间内线段,前开的话左端点加1,右开的话右端点减1.例如[1,3]可以表示成[2,6],(1,3)表示成(3,5). 对于区间的交并补问题,可以转化为区间覆盖问题,若T区间为[a,b]. U T

POJ 3225(线段树)

POJ 3225 题 意 : 区 间 操 作 , 交 , 并 , 补 等 思 路 : 我 们 一 个 一 个 操 作 来 分 析 :( 用 0 和 1 表 示 是 否 包 含 区 间 , - 1 表 示 该 区 间 内 既 有 包 含 又有 不 包 含 ) U : 把 区 间 [l,r ] 覆 盖 成 1 I: 把 [ - ∞ ,l) ( r, ∞ ] 覆 盖 成 0 D : 把 区 间 [l,r ] 覆 盖 成 0 C : 把 [ - ∞ ,l) ( r, ∞ ] 覆 盖 成 0 , 且 [l