POJ 3225 线段树+lazy标记

lazy写崩了…….

查了好久

/*
U—> [l,r]–>1
I—> [1,l-1] [r+1,+无穷] –>0
D—> [l,r]–>0
C—> [1,l-1] [r+1,+无穷]–>0 xor[l,r]
S—> [l,r]–>xor
*/

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 140000
struct Tree{int lazy;bool cover;Tree(){lazy=-1;}}tree[maxn*16];//=0 不选  =1 选   =2 xor
int xx,yy,vis[maxn*2];
char op,Left,Right,f;
void push_down(int pos){
    int lson=pos<<1,rson=pos<<1|1;
    if(tree[pos].lazy==2){
        if(tree[lson].lazy==-1)tree[lson].lazy=2,tree[lson].cover=!tree[lson].cover;
        else if(tree[lson].lazy==2)tree[lson].lazy=-1,tree[lson].cover=!tree[lson].cover;
        else tree[lson].lazy=!tree[lson].lazy,tree[lson].cover=!tree[lson].cover;
        if(tree[rson].lazy==-1)tree[rson].lazy=2,tree[rson].cover=!tree[rson].cover;
        else if(tree[rson].lazy==2)tree[rson].lazy=-1,tree[rson].cover=!tree[rson].cover;
        else tree[rson].lazy=!tree[rson].lazy,tree[rson].cover=!tree[rson].cover;
    }
    else tree[lson].cover=tree[rson].cover=tree[pos].lazy,tree[lson].lazy=tree[rson].lazy=tree[pos].lazy;
    tree[pos].lazy=-1;
}
void update(int l,int r,int pos,int L,int R,int id){
    if(l>=L&&r<=R){
        if(id!=2)tree[pos].cover=id,tree[pos].lazy=id;
        else{
            if(tree[pos].lazy==-1)tree[pos].lazy=2;
            else if(tree[pos].lazy==2)tree[pos].lazy=-1;
            else tree[pos].lazy=!tree[pos].lazy;
            tree[pos].cover=!tree[pos].cover;
        }
        return;
    }
    if(~tree[pos].lazy)push_down(pos);
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    if(mid>=R)update(l,mid,lson,L,R,id);
    else if(mid<L)update(mid+1,r,rson,L,R,id);
    else update(l,mid,lson,L,R,id),update(mid+1,r,rson,L,R,id);
}
void query(int l,int r,int pos,int x){
    if(~tree[pos].lazy)push_down(pos);
    if(l==r){vis[l]=tree[pos].cover;return;}
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    if(mid>=x)query(l,mid,lson,x);
    else query(mid+1,r,rson,x);
}
int main(){
    while(scanf("%c %c%d,%d%c",&op,&Left,&xx,&yy,&Right)!=EOF){
        xx<<=1,yy<<=1;
        if(Left=='(')xx++;if(Right==')')yy--;
        if(xx>yy)xx=yy=maxn-1;
        if(op=='U')update(0,maxn,1,xx,yy,1);
        else if(op=='I'){
            if(xx)update(0,maxn,1,0,xx-1,0);
            update(0,maxn,1,yy+1,maxn,0);
        }
        else if(op=='D')update(0,maxn,1,xx,yy,0);
        else if(op=='C'){
            if(xx)update(0,maxn,1,0,xx-1,0);
            update(0,maxn,1,yy+1,maxn,0);
            update(0,maxn,1,xx,yy,2);
        }
        else if(op=='S')update(0,maxn,1,xx,yy,2);
        getchar();
    }
    for(int i=0;i<maxn;i++)query(0,maxn,1,i);
    xx=-1;
    for(int i=0;i<135000;i++){
        if(vis[i]&&~xx)yy=i;
        else if(!vis[i]){
            if(~xx){
                if(f)printf(" ");
                if(!f)f=1;
                if(xx&1)putchar('(');
                else putchar('[');
                printf("%d,%d",xx>>1,(yy+1)>>1);
                if(yy&1)putchar(')');
                else putchar(']');
            }
            xx=-1;
        }
        else if(vis[i]&&xx==-1)xx=yy=i;
    }
    if(!f)printf("empty set");
}

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值