poj 3225 区间

来源:互联网 发布:angularjs 2.0不用node 编辑:程序博客网 时间:2024/06/01 21:14

poj的中文题哦

果然不是容易写的

光是几个运算符就很让人 头疼

我们来看一看

这里写图片描述

让求最后集合里的数。

可这么多运算怎么弄

需要转换一下喽
一开始有一个大的区间0-maxn
U:把区间[l,r]覆盖成1
I:把[-∞,l)(r,∞]覆盖成0
D:把区间[l,r]覆盖成0
C:把[-∞,l)(r,∞]覆盖成0 , 且[l,r]区间0/1互换
S:[l,r]区间0/1互换‘

所以问题演变成覆盖和xor的线段树嗯哼!

但是第一次写 越界问题没有注意。。

#include<cstdio>#include<algorithm>#include<cstring>#define maxn 666666//#define maxn 10<<1 using namespace std;//by mars_ch//感谢SiriusRen爸爸/*U:把区间[l,r]覆盖成1I:把[-∞,l)(r,∞]覆盖成0D:把区间[l,r]覆盖成0C:把[-∞,l)(r,∞]覆盖成0 , 且[l,r]区间0/1互换S:[l,r]区间0/1互换*/int cover[maxn<<2];//覆盖标记int rev[maxn<<2];//翻转 int vis[maxn<<2];void pushdown(int x){    if(cover[x]!=-1)    {        cover[x*2]=cover[x*2+1]=cover[x];        rev[x*2]=rev[x*2+1]=0;        cover[x]=-1;//完成覆盖标记     }    if(rev[x])    {        if(cover[x*2]!=-1) cover[x*2]^=1;        else rev[x*2]^=1;        rev[x]=0;         if(cover[x*2+1]!=-1) cover[x*2+1]^=1;        else rev[x*2+1]^=1;        rev[x]=0;    }}void updata(int op,int L,int R,int l,int r,int num){    //printf("%d %d %d %d\n",l,r,L,R);    if(l<L || r>R) return;    //printf("twice %d %d %d %d\n",l,r,L,R);    //printf(" llalaal\n");    if(l == L && r ==R)    {        if(op!=-1)//不是覆盖操作 ,当一个节点得到覆盖标记后,翻转标记清空         {            //printf("%d %d %d %d\n",num,op,l,r);            cover[num]=op;            rev[num]=0;         }        else        {            if(cover[num]!=-1) cover[num]^=1;    //如果区间都是0或者1那就直接改变覆盖             else rev[num]^=1;   //不然该翻转标记         }        return;    }    pushdown(num);    int mid=(L+R)/2;    if(r<=mid) updata(op,L,mid,l,r,num*2);    else if(l>mid) updata(op,mid+1,R,l,r,num*2+1);//l>mid不是>=    else    {        updata(op,L,mid,l,mid,num*2);        updata(op,mid+1,R,mid+1,r,num*2+1);    }}void query(int l,int r,int x){    if(cover[x] == 1)    {        for(int i=l;i<=r;i++)        {            vis[i]=true;        }        return ;    }    else if(cover[x] == 0) return;    if(l == r) return ;    pushdown(x);    int mid=(l+r)/2;    query(l,mid,x*2);    query(mid+1,r,x*2+1);}int main(){    char c;    char b,d;    int x,y;    while(scanf("%c %c%d,%d%c\n",&c,&b,&x,&y,&d)!=EOF)    {        x*=2,y*=2;        if(b == '(') x++;        if(d == ')') y--;        if(x>y)x=y=150000;       //非法情况        //printf("%d %d\n",x,y);         if( c == 'U') updata(1,0,maxn,x,y,1);        else if(c == 'D') updata(0,0,maxn,x,y,1);        else if(c == 'I')         {            if(x)updata(0,0,maxn,0,x-1,1);   //数组越界            updata(0,0,maxn,y+1,maxn,1);        }        else if(c == 'C')        {            if(x)updata(0,0,maxn,0,x-1,1);            updata(0,0,maxn,y+1,maxn,1);            updata(-1,0,maxn,x,y,1);        }        else if(c == 'S')        {            updata(-1,0,maxn,x,y,1);        }    }    query(0,maxn,1);    /*for(int i=0;i<=20;i++)    {        printf("%d ",vis[i]);    }    puts("");*/    int s=-1,e;    bool flag=0;    for(int i=0;i<=146666;i++)    {        if(vis[i])        {            if(s == -1)            {                s=i;            }            e=i;        }        else        {            if(s == -1) continue;            if(flag) printf(" ");            printf("%c%d,%d%c",s&1?'(':'[',s>>1,(e+1)>>1,e&1?')':']');            s=-1;            flag=1;        }    }    if(!flag) printf("empty set\n");    else puts("");    return 0;}
0 0
原创粉丝点击