该操作源于此题目
P5568 [SDOI2008]校门外的区间(离散数学应用+线段树+开闭区间处理)难度⭐⭐⭐⭐★
题目中输入的区间有开区间也有闭区间,输出的答案也是有开区间或闭区间,所以这里就需要特殊的开闭区间操作来处理。
详细规则及解释:
代码实现
输出
U [1,5]
D [3,3]
S [2,4]
C (1,5)
I (2,3]
输入
(2,3)
注意这里的输入细节
int main()
{
build(1,0,n);
while(scanf("%s",s)!=EOF)//接受第一个字符
{
ll l,r;
get(l,r);
if(s[0]=='U')update(1,l,r,1);//U是求并集(区间内全部改为1)
else if(s[0]=='I')update(1,0,l-1,0),update(1,r+1,n,0);//I是求交集(区间以外全部为0,不相交就全为0嘛)
else if(s[0]=='D')update(1,l,r,0);//D是减去该区间,所以区间内全为0
else if(s[0]=='C')update(1,0,n,2),update(1,0,l-1,0),update(1,r+1,n,0);//全集范围内01翻转,并将区间的补集覆盖0
else update(1,l,r,2);//区间范围内01翻转
}
print();
return 0;
}
inline void get(ll &l,ll &r)
{
char c=getchar();
while(c!='('&&c!='[')c=getchar();
ll w=(c=='(');l=0;
while(!isdigit(c))c=getchar();
while(isdigit(c))l=(l<<1)+(l<<3)+(c^48),c=getchar();
l<<=1;//乘2是为了区分开区间还是闭区间
l+=w;r=0;//是开区间说明要+1
while(!isdigit(c))c=getchar();
while(isdigit(c))r=(r<<1)+(r<<3)+(c^48),c=getchar();
r<<=1;
while(c!=')'&&c!=']')c=getchar();
r-=(c==')');//处理开闭区间//是开区间说明需要-1
}
inline void print()
{
query(1);
int flag=0,Empty=0;
for(int i=0;i<=n;++i)
{
if(ans[i]&&!flag)//遍历一遍,找到左边界
{
flag=Empty=1;
if(i&1)printf("(%d,",(i-1)>>1);//如果是奇数说明是开区间
else printf("[%d,",i>>1);
}
if(!ans[i]&&flag)
{
flag=0;
if(i&1)printf("%d]\n",(i-1)>>1);//如果是奇数说明是闭区间
else printf("%d)\n",i>>1);
}
}
if(!Empty)
puts("empty set");
}
有任何疑问欢迎评论哦虽然我真的很菜