http://poj.org/problem?id=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 time intervals, which have confused him a lot. Now he badly needs your help. In discrete mathematics, you have studied several basic set operations, namely union, intersection, relative complementation and symmetric difference, which naturally apply to the specialization of sets as intervals.. For your quick reference they are summarized in the table below:
Ikki has abstracted the interval operations emerging from his job as a tiny programming language. He wants you to implement an interpreter for him. The language maintains a set S, which starts out empty and is modified as specified by the following commands:
Input The input contains exactly one test case, which consists of between 0 and 65,535 (inclusive) commands of the language. Each command occupies a single line and appears like
where End of file (EOF) indicates the end of input. Output Output the set S as it is after the last command is executed as the union of a minimal collection of disjoint intervals. The intervals should be printed on one line separated by single spaces and appear in increasing order of their endpoints. If S is empty, just print “ Sample Input U [1,5] D [3,3] S [2,4] C (1,5) I (2,3] Sample Output (2,3) Source |
题意:
这题的language可以选中文,点我点我点我
分析:
U:[a,b] 置为1;
I:[0,a),(b,INF)置为0;
D:[a,b]置为0;
C:[0,a),(b,INF)置为0,[a,b]xor 1;
S:[ a,b] xor 1.
因为是区间更新,要用到lazy,异或运算能处理就立刻处理,不能处理就先记录。
对于区间的开闭,我们可以将坐标放大,偶数为闭,奇数为开。
很容易写晕的代码,要小心谨慎(明明是自己太弱还要找理由>_<)
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<cctype>
#include<cmath>
#include<string>
#include<cstring>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<map>
#include<set>
#define sqr(x) ((x)*(x))
#define LL long long
#define itn int
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
#define eps 1e-10
#define maxm
#define maxn 65536
using namespace std;
int setv[maxn<<3],XOR[maxn<<3];//setv[k]为-1表示区间内值不同,不能立刻进行xor运算
int pos[maxn<<1];
void pushxor(int k)
{
if (setv[k]!=-1)
setv[k]^=1;
else
XOR[k]^=1;
}
void pushdown(int k)
{
if (setv[k]!=-1)
{
setv[k*2+1]=setv[k*2+2]=setv[k];
setv[k]=-1;
XOR[k*2+1]=XOR[k*2+2]=0;
}
if (XOR[k])
{
pushxor(k*2+1);pushxor(k*2+2);
XOR[k]=0;
}
}
void update(int a,int b,int v,int k,int l,int r)
{
if (b<=l || r<=a) return;
if (a<=l && r<=b)
{
setv[k]=v;
XOR[k]=0;
}
else
{
pushdown(k);
update(a,b,v,k*2+1,l,l+r>>1);
update(a,b,v,k*2+2,l+r>>1,r);
}
}
void change(int a,int b,int k,int l,int r)
{
if (b<=l || r<=a) return;
if (a<=l && r<=b)
{
if (setv[k]!=-1)
setv[k]^=1;
else
{
XOR[k]^=1;
}
}
else
{
pushdown(k);
change(a,b,k*2+1,l,l+r>>1);
change(a,b,k*2+2,l+r>>1,r);
}
}
void query(int k,int l,int r)
{
if (r-l==1)
{
pos[l]=setv[k]^XOR[k];
return ;
}
pushdown(k);
query(k*2+1,l,l+r>>1);
query(k*2+2,l+r>>1,r);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("/home/fcbruce/文档/code/t","r",stdin);
#endif // ONLINE_JUDGE
itn n=65536<<1;
char op,ll,rr;
int a,b;
while (~scanf("%1s ",&op))
{
scanf("%c%d,%d%c",&ll,&a,&b,&rr);
a<<=1;b<<=1;
if (ll=='(') a++;
if (rr==')') b--;
if (op=='U') update(a,b+1,1,0,0,n);
if (op=='I')
{
update(0,a,0,0,0,n);
update(b+1,n,0,0,0,n);
}
if (op=='D')
{
update(a,b+1,0,0,0,n);
}
if (op=='C')
{
update(0,a,0,0,0,n);
update(b+1,n,0,0,0,n);
change(a,b+1,0,0,n);
}
if (op=='S')
{
change(a,b+1,0,0,n);
}
}
query(0,0,n);
int L,R;
R=L=-1;
bool flag=false;
for (int i=0;i<n;i++)
{
if (pos[i])
{
R=L=i;
while (pos[R+1]) R++;
}
if (R!=-1)
{
if (flag) putchar(' ');
printf("%c%d,%d%c",L&1?'(':'[',L>>1,R+1>>1,R&1?')':']');
flag=true;
i=R;
L=R=-1;
}
}
if (!flag) printf("empty set");
puts("");
return 0;
}