您的位置:首页 > 其它

poj 3225 线段树注意lazy标记

2013-03-20 19:31 302 查看
题意令人很忧伤,理解了题意就好办了。题目中集合中的数不只是整数,将线段扩大两倍用于表示开区间,然后用个懒惰标记就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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: