博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj3225 Help with Intervals
阅读量:4636 次
发布时间:2019-06-09

本文共 3225 字,大约阅读时间需要 10 分钟。

 操作含义:

我们一个一个操作来分析:(用0和1表示是否包含区间,-1表示该区间内既有包含又有不包含)

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互换

COVER[ID]=1表示用1覆盖去见,COVER[ID]=0,表示用0覆盖区间,COVER[ID]=-1,表示其子区间既有1覆盖又有0覆盖的请款,

对于每个节点使用覆盖或者异或操作标记延迟,1:如果一个区间遇上覆盖标记,则其异或标清空,2:如果一个区间是覆盖标记,pushdown操作使得其孩子区间的异或标志位变为0,孩子的覆盖标志等于其父代的标志。3如果其异或标记存在,Pushdown操作检查孩子的的覆盖标志,如果存在,则孩子覆盖标志直接变为原来的反,否者孩子的异或标志变为原来的反,异或1可以取得原来的反,4:操作保证每一个节点只存在一个覆盖标记或者异标志,

#include
#include
#include
#include
#define MAXN 131072int c_cover[MAXN<<2],c_xor[MAXN<<2];bool hash[MAXN+10];void update(char op,int left,int right,int l,int r,int id);void f_xor(int id);void push_down(int id);void push_down(int id);void query(int l,int r,int id);int main(){ char op,c_left,c_right; int i,left,right; c_xor[1]=0; c_cover[1]=0; while(~scanf("%c %c%d,%d%c\n",&op,&c_left,&left,&right,&c_right)) { left<<=1; right<<=1; if(c_left=='(') left++; if(c_right==')') right--; if(left>right) { if(op=='C'||op=='I') c_cover[1]=c_xor[1]=0; } else update(op,left,right,0,MAXN,1); } query(0,MAXN,1); int a=-1,b; bool flag=false; for(i=0;i<=MAXN;i++) { if(hash[i]) { b=i; if(a==-1)a=i; } else if(a!=-1) { if(flag) printf(" "); printf("%c%d,%d%c",a&1?'(':'[',a>>1,(b+1)>>1,b&1?')':']'); flag=true; a=-1; } } if(!flag) printf("empty set"); puts("");}void update(char op,int left,int right,int l,int r,int id){ if(left<=l&&right>=r) { if(op=='U') { c_cover[id]=1; c_xor[id]=0; } else if(op=='D') { c_cover[id]=0; c_xor[id]=0; } else if(op=='S'||op=='C') { f_xor(id); } return ; } push_down(id); int mid=(l+r)>>1; if(left<=mid) update(op,left,right,l,mid,id<<1); else if(op=='I'||op=='C') { c_cover[id<<1]=0; c_xor[id<<1]=0; } if(right>mid) { update(op,left,right,mid+1,r,id<<1|1); } else if(op=='I'||op=='C') { c_cover[id<<1|1]=0; c_xor[id<<1|1]=0; }}void f_xor(int id){ if(c_cover[id]!=-1) c_cover[id]^=1; else c_xor[id]^=1;}void push_down(int id){ if(c_cover[id]!=-1) { c_cover[id<<1]=c_cover[id<<1|1]=c_cover[id]; c_xor[id<<1]=c_xor[id<<1|1]=0; c_cover[id]=-1; } if(c_xor[id]) { f_xor(id<<1); f_xor(id<<1|1); c_xor[id]=0; }}void query(int l,int r,int id){ if(c_cover[id]==1) { int i; for(i=l;i<=r;i++) { hash[i]=1; } return ; } else if(c_cover[id]==0) return ; if(l==r) return ; push_down(id); int mid=(l+r)>>1; query(l,mid,id<<1); query(mid+1,r,id<<1|1);}

转载于:https://www.cnblogs.com/woaiyy/archive/2012/06/11/2544497.html

你可能感兴趣的文章
adb命令 判断锁屏
查看>>
centos7下安装docker
查看>>
推荐一个MacOS苹果电脑系统解压缩软件
查看>>
命令行编译运行CSharp文件
查看>>
HDOJ 1060 Leftmost Digit
查看>>
1035等差数列末项计算
查看>>
ASP.NET MVC 2示例Tailspin Travel
查看>>
nonatomic, retain,weak,strong用法详解
查看>>
第10周进度条
查看>>
编写函数求两个整数 a 和 b 之间的较大值。要求不能使用if, while, switch, for, ?: 以 及任何的比较语句。...
查看>>
CDMA鉴权
查看>>
ASP.NET MVC Identity 兩個多個連接字符串問題解決一例
查看>>
#include<bits/stdc++.h>包含C++的所有头文件
查看>>
Vue插槽 slot
查看>>
软考之路-网络攻击:主动攻击和被动攻击
查看>>
《windows核心编程系列》二谈谈ANSI和Unicode字符集
查看>>
知识图谱学习笔记(1)
查看>>
第三方原理
查看>>
同意好友
查看>>
随机映射
查看>>