该操作源于此题目

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");
}

有任何疑问欢迎评论哦虽然我真的很菜