poj 3225 线段树注意lazy标记

来源:互联网 发布:linux怎么卸载vsftpd 编辑:程序博客网 时间:2024/05/21 18:26

题意令人很忧伤,理解了题意就好办了。题目中集合中的数不只是整数,将线段扩大两倍用于表示开区间,然后用个懒惰标记就ok了。

#include<stdio.h>#include<iostream>#include<algorithm>#include<string.h>using namespace std;const int nMax=140005;const int N=65535*2+2;int res,vis[nMax];struct Tree{    int l,r,f;    char lazy;}t[nMax<<2];#define mid ((t[p].l+t[p].r)>>1)#define ls (p<<1)#define rs ((ls)+1)void slove(int p){    if(t[p].lazy=='U') t[p].lazy='I';    else if(t[p].lazy=='I') t[p].lazy='U';    else if(t[p].lazy=='C') t[p].lazy='E';    else t[p].lazy='C';}void pushdown(int p){    if(t[p].lazy!='E')    {        if(t[p].lazy=='U') t[ls].f=t[rs].f=1;        else if(t[p].lazy=='I') t[ls].f=t[rs].f=0;        else t[ls].f^=1,t[rs].f^=1;        if(t[p].lazy=='U' || t[p].lazy=='I')            t[ls].lazy=t[rs].lazy=t[p].lazy;        else        {           slove(ls); slove(rs);        }        t[p].lazy='E';    }}void maketree(int p,int l,int r){    t[p].l=l;t[p].r=r;t[p].lazy='E';t[p].f=0;    if(t[p].l==t[p].r) return;    maketree(ls,l,mid);    maketree(rs,mid+1,r);}void modify(int p,int l,int r,char c){    if(l>r) return;    if(t[p].l==l&&t[p].r==r)    {        if(c=='U') t[p].f=1;        else if(c=='I') t[p].f=0;        else t[p].f^=1;        if(c=='U'||c=='I') t[p].lazy=c;        else slove(p);        return;    }    pushdown(p);    if(r<=mid) modify(ls,l,r,c);    else if(l>=mid+1) modify(rs,l,r,c);    else    {        modify(ls,l,mid,c);        modify(rs,mid+1,r,c);    }}void query(int p){    if(t[p].l==t[p].r)    {        if(t[p].f)        {            vis[t[p].l]=1;res++;        }        return ;    }    pushdown(p);    query(ls); query(rs);}int main(){//      freopen("test.txt","r",stdin);      maketree(1,0,N);      char c,b1,b2;      int l,r;      while(scanf("%c %c%d,%d%c",&c,&b1,&l,&r,&b2)!=EOF)      {          getchar();          if(b1=='[') l*=2;          else l=l*2+1;          if(b2==']') r*=2;          else r=r*2-1;          if(c=='U') modify(1,l,r,'U');          else if(c=='I')          {              modify(1,0,l-1,'I'); modify(1,r+1,N,'I');          }          else if(c=='D') modify(1,l,r,'I');          else if(c=='C')          {              modify(1,0,l-1,'I');modify(1,r+1,N,'I');              modify(1,l,r,'C');          }          else modify(1,l,r,'C');      }      memset(vis,0,sizeof(vis));res=0;      query(1);      int flag=0;      for(int i=0;i<=N;i++)      {          if(vis[i] && !flag)          {              flag=1;              printf("%c%d,",(i%2==0?'[':'('),i/2);          }          if(!vis[i] && flag)          {              flag=0;              printf("%d%c ",i/2,(i%2?']':')'));          }      }      if(!res) printf("empty set");      printf("\n");      return 0;}

 

原创粉丝点击