poj 3225 线段树+位运算
略复杂的一道题,首先要处理开闭区间问题,扩大两倍即可,注意输入最后要\n,初始化不能随便memset
采用线段树,对线段区间进行0,1标记表示该区间是否包含在s内
U T S ← S ∪ T 即将[l,r]标记为1
I T S ← S ∩ T 即将-oo~l和r~+oo标记为0,因为是并集,所以并集后的集合s一定在[l,r]内,则在l,r内的集合被标记是什么状态就是什么状态(表示是否属于s),[l,r]外的集合不属于s所以标记为0
D T S ← S - T 即将[l,r]标记为0,则在[l,r]内被s包含的集合也会标记为0表示不再属于s
C T S ← T - S 即先将-oo~l,r~+oo标记为0,这部分不属于[l,r]则一定不属于s,然后将[l,r]的标记0/1互换,因为属于s的不再属于s,不属于s的将属于s
S T S ← S ⊕ T 即属于s的不变,[l,r]中不属于s的(区间)0标记为1,属于s的(区间)1标记为0,所以[l,r]的标记0/1互换
最后对区间l,r标记时标记将l*2,r*2标记,如果是闭区间则对l*2+1,或r*2-1进行标记,则输出的时候只需判断奇偶就能判断开闭区间
是否覆盖0,1是否转换0,1的0,1转换都可以用异或去转换
Sample Input
U [1,5]
D [3,3]
S [2,4]
C (1,5)
I (2,3]
Sample Output
(2,3)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn=;
int tot=;
int n,m,t;
int Xor[maxn<<],cov[maxn<<]; //异或标记,覆盖标记
int hash[maxn<<];
void XXor(int rt)
{
if(cov[rt]!=-) cov[rt]^=; //说明该区域有值存在
else Xor[rt]^=;
}
void pushdown(int rt)
{
if(cov[rt]!=-)
{
cov[rt<<]=cov[rt<<|]=cov[rt];
Xor[rt<<]=Xor[rt<<|]=;
cov[rt]=-;
}
if(Xor[rt])
{
XXor(rt<<);
XXor(rt<<|);
Xor[rt]=;
}
}
void update(char op,int L,int R,int l,int r,int rt)
{
if(l>=L&&r<=R)
{ if(op=='U') cov[rt]=,Xor[rt]=;
else if(op=='D') cov[rt]=Xor[rt]=;
else if(op=='C'||op=='S') XXor(rt);
return;
}
pushdown(rt);
int m=(l+r)>>;
if(L<=m) update(op,L,R,lson);
else if(op=='I'||op=='C') cov[rt<<]=Xor[rt<<]=;
if(m<R) update(op,L,R,rson);
else if(op=='I'||op=='C') cov[rt<<|]=Xor[rt<<|]=;
}
void query(int l,int r,int rt)
{
if(cov[rt]==)
{
for(int i=l;i<=r;i++) hash[i]=;
return;
}
else if(cov[rt]==) return;
if(l==r) return;
pushdown(rt);
int m=(r+l)>>;
query(lson);
query(rson);
}
int main()
{
int i,j,k;
//freopen("1.in","r",stdin);
char l,r,op;
int a,b;
while(scanf("%c %c%d,%d%c\n",&op,&l,&a,&b,&r)!=EOF)
{
a<<=,b<<=; //区间扩大一倍,解决开闭区间问题
//printf("%d %d\n",a,b);
if(l=='(') a++;
if(r==')') b--;
if(a>b) //说明a和b的值相等
{
if(op=='C'||op=='I') cov[]=Xor[]=,printf(""); //整个区间为0
}
else update(op,a,b,,maxn,);
}
k=;
query(,maxn,); //此时区间内的有效区域值为1
int s=-,e; //判断左右区间位置 for(i=;i<=maxn;i++)
{
if(hash[i]) //该区域被覆盖
{
if(s==-) s=i;
e=i;
}
else
{
if(s!=-) //说明存在一个完整区间
{
if(k++) printf(" ");
printf("%c%d,%d%c",s&?'(':'[',s>>,(e+)>>,e&?')':']'); //&运算用来判断奇偶,偶数的话二进制末位为0,and1得0,说明为闭区间
s=-;
}
}
}
if(k==) printf("empty set");
puts("");
return ;
}
poj 3225 线段树+位运算的更多相关文章
- poj 2777 Count Color - 线段树 - 位运算优化
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 42472 Accepted: 12850 Description Cho ...
- POJ 2777 Count Color(线段树+位运算)
题目链接:http://poj.org/problem?id=2777 Description Chosen Problem Solving and Program design as an opti ...
- hdu 5023 线段树+位运算
主要考线段树的区间修改和区间查询,这里有一个问题就是这么把一个区间的多种颜色上传给父亲甚至祖先节点,在这里题目告诉我们最多30颜色,那么我们可以把这30中颜色用二进制储存和传给祖先节点,二进制的每一位 ...
- Codeforces 620E New Year Tree(线段树+位运算)
题目链接 New Year Tree 考虑到$ck <= 60$,那么用位运算统计颜色种数 对于每个点,重新标号并算出他对应的进和出的时间,然后区间更新+查询. 用线段树来维护. #includ ...
- Count Color(线段树+位运算 POJ2777)
Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 39917 Accepted: 12037 Descrip ...
- Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)
链接: https://codeforces.com/contest/1234/problem/D 题意: You are given a string s consisting of lowerca ...
- POJ 3225 线段树区间更新(两种更新方式)
http://blog.csdn.net/niuox/article/details/9664487 这道题明显是线段树,根据题意可以知道: (用0和1表示是否包含区间,-1表示该区间内既有包含又有不 ...
- poj_2777线段树+位运算
第一次没想到用位运算,不出意料的T了,,, PS:在床上呆了接近两个月后,我胡汉三又杀回来刷题啦-- #include<iostream> #include<cstdio> # ...
- 【洛谷】【线段树+位运算】P2574 XOR的艺术
[题目描述:] AKN觉得第一题太水了,不屑于写第一题,所以他又玩起了新的游戏.在游戏中,他发现,这个游戏的伤害计算有一个规律,规律如下 1. 拥有一个伤害串为长度为n的01串. 2. 给定一个范围[ ...
随机推荐
- jquery uploadify 进入页面请求两次问题解决办法。
this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url);this.settings.button_imag ...
- linux的vnc- rdesktop远程登录windows桌面
使用vnc来实现任何平台之间(windows, linux, mac等)的远程桌面互访 vnc:virtual network computing 分 vnc server和 vnc client 在 ...
- logback 常用配置详解(二)
<appender> <appender>: <appender>是<configuration>的子节点,是负责写日志的组件. <appende ...
- Entity Framework Repository模式
Repository模式之前 如果我们用最原始的EF进行设计对每个实体类的“C(增加).R(读取).U(修改).D(删除)”这四个操作. 第一个:先来看看查询,对于实体类简单的查询操作,每次都是这样的 ...
- java笔记--查看和修改线程的优先级
查看和修改线程的优先级 java中每一个线程都有优先级属性,在默认情况下,新建的线程的优先级与创建该线程的线程优先级相同.每当线程调度器选择要运行的线程时,通常选择优先级较高的线程. 注:线程的优先级 ...
- lucene搜索方式(query类型)
Lucene有多种搜索方式,可以根据需要选择不同的方式. 1.词条搜索(单个关键字查找) 主要对象是TermQuery 调用方式如下: Term term=new Term(字段名,搜索关键字);Qu ...
- 计蒜客 X的平方根
X的平方根 设计函数int sqrt(int x),计算x的平方根. 格式: 输入一个数x,输出它的平方根.直到碰到结束符号为止. 千万注意:是int类型哦- 输入可以如下操作: while(cin& ...
- Linux 日志文件utmp、wtmp、lastlog、messages
1.有关当前登录用户的信息记录在文件utmp中:==who命令 2.登录进入和退出纪录在文件wtmp中:==w命令 3.最后一次登录文件可以用lastlog命令察看: 4.messag ...
- failed to load session "ubuntu"
https://answers.launchpad.net/ubuntu/+source/gnome-desktop/+question/211792
- set_include_path详细解释
zendframework的示例index.php里有这样一句 set_include_path('.' . PATH_SEPARATOR . '../library/'. PATH_SEPARATO ...