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; }
相关文章推荐
- POJ 3468-A Simple Problem with Integers(线段树_区间更新+lazy标记)
- poj 3468 A Simple Problem with Integers(线段树成段更新,延迟标记,Lazy)
- poj-2777 线段树lazy标记+位运算
- poj 3225 Help with Intervals -线段树-延迟标记-区间交并补
- POJ 2777 count color(线段树,lazy标记)
- poj 3225 Help with Intervals 线段树lazy-tag求解区间运算
- hdu 1698 poj 3468 线段树 成段更新(lazy标记)
- POJ 3225 区间(带标记的线段树区间操作)
- 基本线段树(标记下传lazy-tag思想)poj 2468 A Simple Problem with Integers
- poj1436(线段树lazy标记)
- poj 1823 Hotel 线段树,注意懒惰标记,不标记就会超时滴
- POJ 3225 Help with Intervals (线段树 成段更新, 懒惰标记*2)
- poj 4047 Garden 线段树lazy标记与成段更新
- poj 3468 线段树 lazy标记模板
- POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)
- POJ 3468 A Simple Problem with Integers(线段树成段更新+lazy标记)
- POJ 3667 线段树 + 延迟标记 + 区间处理
- poj 3468 A Simple Problem with Integers 线段树加延迟标记
- POJ 3225 (线段树 区间更新) Help with Intervals
- POJ 3667 Hotel 【线段树 区间合并 + Lazy-tag】