3226: [Sdoi2008]校门外的区间 线段树

一个sb错误调了一晚上!!!标记清零在pushdown最后然后中间return了!!!


我已经完全没有心情写题解了

#include<iostream>
#include<cstdio>
#define n 131073
using namespace std;
char opt[5];
int l[n<<2],r[n<<2],val[n<<2],tag[n<<2],rev[n<<2];
inline int read()
{
    int a=0,f=0; char c=getchar();
    while (c<'0'||c>'9') {if (c=='(') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    if (c==')') f=1;
    return a*2-f;
}
inline void pushdown(int k)
{
    if (l[k]==r[k])
    {
        if (tag[k]!=-1) val[k]=tag[k];
        if (rev[k]) val[k]^=1;
        tag[k]=-1; rev[k]=0;  //!!!!!!!
        return;
    }
    if (tag[k]!=-1)
    {
        tag[k<<1]=tag[k<<1|1]=tag[k];
        rev[k<<1]=rev[k<<1|1]=0;
    }
    if (rev[k]) rev[k<<1]^=1,rev[k<<1|1]^=1;
    rev[k]=0; tag[k]=-1;
}
void build(int k,int x,int y)
{
    l[k]=x; r[k]=y; tag[k]=-1;
    if (l[k]==r[k]) return;
    int mid=l[k]+r[k]>>1;
    build(k<<1,x,mid); build(k<<1|1,mid+1,y);
}
void modify(int k,int x,int y,int val)
{
    if (x>y) return;
    pushdown(k);
    if (l[k]==x&&r[k]==y)
    {
        tag[k]=val;
        return;
    }
    int mid=l[k]+r[k]>>1;
    if (y<=mid) modify(k<<1,x,y,val);
    else if (x>mid) modify(k<<1|1,x,y,val);
    else modify(k<<1,x,mid,val),modify(k<<1|1,mid+1,y,val);
}
void rever(int k,int x,int y)
{
    if (x>y) return;
    pushdown(k);
    if (l[k]==x&&r[k]==y)
    {
        rev[k]^=1;
        return;
    }
    int mid=l[k]+r[k]>>1;
    if (y<=mid) rever(k<<1,x,y);
    else if (x>mid) rever(k<<1|1,x,y);
    else rever(k<<1,x,mid),rever(k<<1|1,mid+1,y);
}
int query(int k,int x)
{
    pushdown(k);
    if (l[k]==r[k]) return val[k];
    int mid=l[k]+r[k]>>1;
    if (x<=mid) return query(k<<1,x);
    else return query(k<<1|1,x);
}
int main()
{
    build(1,1,n);
    while (scanf("%s",opt)!=EOF)
    {
        int a=read()+2,b=read()+2;
        switch(opt[0])
        {
            case 'U':
                modify(1,a,b,1);
                break;
            case 'I':
                modify(1,1,a-1,0);
                modify(1,b+1,n,0);
                break;
            case 'D':
                modify(1,a,b,0);
                break;
            case 'C':
                modify(1,1,a-1,0);
                modify(1,b+1,n,0);
                rever(1,a,b);
                break;
            case 'S':
                rever(1,a,b);
                break;
        }
    }
    int st=-1,en=-1,flag=0;
    for (int i=1;i<=n;i++)
        if (query(1,i))
        {
            if (st==-1) st=i; en=i;
        }
        else
        {
            if (st!=-1)
            {
                if (flag) putchar(' '); else flag=1;
                if (st&1) putchar('('); else putchar('[');
                printf("%d,%d",(st>>1)-1,((en+1)>>1)-1);
                if (en&1) putchar(')'); else putchar(']');
            }
            st=en=-1;
        }
    if (!flag) puts("empty set");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值