您的位置:首页 > 其它

BZOJ 题目 3226: [Sdoi2008]校门外的区间(线段树区间交并差异或)

2015-09-06 00:32 330 查看

3226: [Sdoi2008]校门外的区间

Time Limit: 10 Sec Memory Limit: 128 MB

Submit: 486 Solved: 181

[Submit][Status][Discuss]

Description

[align=left] [/align]
  受校门外的树这道经典问题的启发,A君根据基本的离散数学的知识,抽象出5种运算维护集合S(S初始为空)并最终输出S。现在,请你完成这道校门外的树之难度增强版——校门外的区间。

  5种运算如下:
[align=center]U T[/align]
[align=center]S∪T[/align]
[align=center]I T[/align]
[align=center]S∩T[/align]
[align=center]D T[/align]
[align=center]S-T[/align]
[align=center]C T[/align]
[align=center]T-S[/align]
[align=center]S T[/align]
[align=center]S⊕T[/align]
  基本集合运算如下:
[align=center]A∪B[/align]
[align=center]{x : xÎA or xÎB}[/align]
[align=center]A∩B[/align]
[align=center]{x : xÎA and xÎB}[/align]
[align=center]A-B[/align]
[align=center]{x : xÎA and xÏB}[/align]
[align=center]A⊕B[/align]
[align=center](A-B)∪(B-A)[/align]

Input

  输入共M行。
  每行的格式为X T,用一个空格隔开,X表示运算的种类,T为一个区间(区间用(a,b), (a,b], [a,b), [a,b]表示)。

Output

  共一行,即集合S,每个区间后面带一个空格。若S为空则输出"empty set"。

Sample Input

U [1,5]

D [3,3]

S [2,4]

C (1,5)

I (2,3]

Sample Output

(2,3)

HINT

对于 100% 的数据,0≤a≤b≤65535,1≤M≤70000

Source

线段树
用getchar()re,。。
ac代码
/**************************************************************
Problem: 3226
User: kxh1995
Language: C++
Result: Accepted
Time:548 ms
Memory:6948 kb
****************************************************************/

#include<stdio.h>
#include<string.h>
#define maxn 131072
struct s
{
int cover,Xor;
}node[maxn<<2];
int hash[maxn<<2];
void fxor(int tr)
{
if(node.cover!=-1)
node.cover^=1;
else
node.Xor^=1;
}
void pushdown(int tr)
{
if(node.cover!=-1)
{
node[tr<<1].cover=node[tr<<1|1].cover=node.cover;
node[tr<<1].Xor=node[tr<<1|1].Xor=0;
node.cover=-1;
}
if(node.Xor)
{
fxor(tr<<1);
fxor(tr<<1|1);
node.Xor=0;
}
}
void update(char op,int L,int R,int l,int r,int tr)
{
if(L<=l&&r<=R)
{
if(op=='U')
{
node.cover=1;
node.Xor=0;
}
else
if(op=='D')
{
node.cover=0;
node.Xor=0;
}
else
if(op=='C'||op=='S')
fxor(tr);
return;
}
pushdown(tr);
int mid=(l+r)>>1;
if(L<=mid)
{
update(op,L,R,l,mid,tr<<1);
}
else
{
if(op=='I'||op=='C')
node[tr<<1].Xor=node[tr<<1].cover=0;
}
if(mid<R)
{
update(op,L,R,mid+1,r,tr<<1|1);
}
else
{
if(op=='I'||op=='C')
node[tr<<1|1].Xor=node[tr<<1|1].cover=0;
}
}
void query(int l,int r,int tr)
{
if(node.cover==1)
{
for(int i=l;i<=r;i++)
hash[i]=1;
return;
}
else
if(node.cover==0)
return;
if(l==r)
return;
pushdown(tr);
int mid=(l+r)>>1;
query(l,mid,tr<<1);
query(mid+1,r,tr<<1|1);
}
int main()
{
node[1].cover=node[1].Xor=0;
char op,a,b;
int x,y;
while(scanf("%c %c%d,%d%c\n",&op,&a,&x,&y,&b)!=EOF)
{
x<<=1;
y<<=1;
if(a=='(')
x++;
if(b==')')
y--;
if(x>y)
{
if(op=='I'||op=='C')
{
node[1].cover=node[1].Xor=0;
}
}
update(op,x,y,0,maxn,1);
}
query(0,maxn,1);
int s=-1,t,flag=0;
for(int i=0;i<=maxn;i++)
{
if(hash[i])
{
if(s==-1)
s=i;
t=i;
}
else
{
if(s!=-1)
{
if(flag==1)
printf(" ");
flag=1;
if(s&1)
a='(';
else
a='[';
if(t&1)
b=')';
else
b=']';
printf("%c%d,%d%c",a,s>>1,(t+1)>>1,b);
s=-1;
}
}
}
if(flag==0)
printf("empty set\n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: