3226: [Sdoi2008]校门外的区间

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 615  Solved: 227
[Submit][Status][Discuss]

Description

 
  受校门外的树这道经典问题的启发,A君根据基本的离散数学的知识,抽象出5种运算维护集合S(S初始为空)并最终输出S。现在,请你完成这道校门外的树之难度增强版——校门外的区间。
 
  5种运算如下:
U T
S∪T
I T
S∩T
D T
S-T
C T
T-S
S T
S⊕T
  基本集合运算如下:
A∪B
{x : xÎA or xÎB}
A∩B
{x : xÎA and xÎB}
A-B
{x : xÎA and xÏB}
A⊕B
(A-B)∪(B-A)
 

Input

  输入共M行。
  每行的格式为X T,用一个空格隔开,X表示运算的种类,T为一个区间(区间用(a,b), (a,b], [a,b), [a,b]表示)。
 

Output

 
  共一行,即集合S,每个区间后面带一个空格。若S为空则输出"empty set"。
 

Sample Input

U [1,5]
D [3,3]
S [2,4]
C (1,5)
I (2,3]

Sample Output

(2,3)

HINT

对于 100% 的数据,0≤a≤b≤65535,1≤M≤70000

Source

【思路】

线段树。

因为开区间所以扩大一倍就好了。

   转化集合操作为线段树上的操作

U 将a,b设为1

I 将1..a-1,b+1..n设为0

D 将a..b设为0

C 将1..a-1,b+1..n设为0 取反a..b

S 取反a..b

写一个支持set与取反的线段树。

【代码】

 #include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std; const int N = +; struct Tree{ int l,r,v,setv,rev; }T[N<<]; void build(int u,int L,int R) {
T[u].l=L,T[u].r=R,T[u].setv=-;T[u].rev=;
if(L==R) return ;
int M=(L+R)>>;
build(u<<,L,M); build(u<<|,M+,R);
}
void pushdown(int u) {
int lc=u<<,rc=lc|;
if(T[u].l==T[u].r) {
if(T[u].setv!=-) T[u].v=T[u].setv;
T[u].v^=T[u].rev;
}
else {
if(T[u].setv!=-) { //AT: set->rev=0 所以rev的执行顺序在set之后
T[lc].setv=T[rc].setv=T[u].setv;
T[lc].rev=T[rc].rev=;
}
T[lc].rev^=T[u].rev,T[rc].rev^=T[u].rev;
}
T[u].setv=-, T[u].rev=;
}
void update(int u,int L,int R,int x) {
pushdown(u);
if(L<=T[u].l && T[u].r<=R) {
if(x==-) T[u].rev^=;
else T[u].setv=x;
}
else {
int M=(T[u].l+T[u].r)>>;
if(L<=M) update(u<<,L,R,x);
if(M<R) update(u<<|,L,R,x);
}
}
int query(int u,int x) {
pushdown(u);
if(T[u].l==T[u].r) return T[u].v;
else {
int M=(T[u].l+T[u].r)>>;
if(x<=M) return query(u<<,x);
else return query(u<<|,x);
}
}
void reverse(int u,int L,int R) { update(u,L,R,-); } char s[];
void read(int& x) {
char c=getchar(); int f=; x=;
while(!isdigit(c)) { if(c=='(') f=; c=getchar(); }
while(isdigit(c))
x=x*+c-'' , c=getchar();
if(c==')') f=-;
x=x*+f;
}
int main() {
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
int n=*+;
build(,,n);
while(scanf("%s",s)==) {
int a,b;
read(a),read(b);
a+=; b+=;
switch(s[]) {
case 'U':
update(,a,b,); break;
case 'I':
update(,,a-,),update(,b+,n,); break;
case 'D':
update(,a,b,); break;
case 'C':
update(,,a-,),update(,b+,n,);
reverse(,a,b); break;
case 'S':
reverse(,a,b); break;
}
}
int f=-,r=-,flag=;
for(int i=;i<=n;i++)
{
if(query(,i)) { if(f==-) f=i; r=i; }
else {
if(f!=-) {
if(flag) putchar(' ');
else flag=;
if(f&) putchar('(');
else putchar('[');
printf("%d,%d",f/-,(r+)/-);
if(r&) putchar(')');
else putchar(']');
}
f=r=-;
}
}
if(!flag) puts("empty set");
return ;
}

bzoj 3226 [Sdoi2008]校门外的区间(线段树)的更多相关文章

  1. BZOJ 3226: [Sdoi2008]校门外的区间

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3226 题意:初始集合S为空.模拟四种集合操作:集合并.交.差.补集并. 思路:区间 ...

  2. [SDOI2008] 校门外的区间 - 线段树

    U T 即将区间 \(T\) 范围赋值为 \(1\) I T 即将区间 \(U - T\) 范围赋值为 \(0\) D T 即将区间 \(T\) 赋值为 \(0\) C T 由于 \(S=T-S=T( ...

  3. [bzoj3226][Sdoi2008]校门外的区间——线段树

    题目 略 题解 直接套黄学长模板. Orz 代码 #include <bits/stdc++.h> using namespace std; #define ll long long #d ...

  4. 3226. [SDOI2008]校门外的区间【线段树】

    Description   受校门外的树这道经典问题的启发,A君根据基本的离散数学的知识,抽象出5种运算维护集合S(S初始为空)并最终输出S.现在,请你完成这道校门外的树之难度增强版——校门外的区间. ...

  5. 3226: [Sdoi2008]校门外的区间

    链接 思路 bug漫天飞... 维护一颗线段树,支持区间赋值,和区间异或.因为会处理到一些方括号还是圆括号的问题,所以对于每一个下标都乘2,假设中间有一个.5即可,都变成了方括号,输出在处理一下. U ...

  6. BZOJ-3226 校门外的区间 线段数+拆点(类似的思想)

    shabi题....bzoj关键字检查freopen??可怕,,1A的卡了一小时.... 3226: [Sdoi2008]校门外的区间 Time Limit: 10 Sec Memory Limit: ...

  7. BZOJ3226[Sdoi2008]校门外的区间 题解

    题目大意: 有5种运算维护集合S(S初始为空)并最终输出S. 5种运算如下: U T  S∪T I T S∩T D T  S-T C T T-S S T S⊕T 基本集合运算如下: A∪B {x : ...

  8. 「BZOJ3226」[Sdoi2008]校门外的区间

    题目 首先是开闭区间的处理,我们把\(1.5\)这种数加进来,用\([1.5,6]\)来表示\((2,6]\) 根据离散数学的基本知识,尝试把五个操作转化成人话 把\([x,y]\)变成\(1\) 把 ...

  9. BZOJ3226: [Sdoi2008]校门外的区间

    感觉很有趣的题呢. 每个点拆成两个,线段树维护. 不过这题难点其实在输入输出. #include<bits/stdc++.h> #define N (1<<17) #defin ...

随机推荐

  1. 利用反射生成SQL语句

    // 修改学员信息的方法 public bool ModifyStudent(MODEL.Students model) { // 利用反映获取类对所有属性,用来动态生成SQL语句 StringBui ...

  2. e.target与事件委托简例

    target定义: target 事件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素.文档或窗口. 语法: event.target event.target.nodeName  // ...

  3. Python的简介以及安装和第一个程序以及用法

    Python的简介: 1.Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.自从20世纪90年代初Python语言诞生至今,它逐渐被广泛应用于处理系统管理任务和Web编程.Pytho ...

  4. Mysql 与 php动态网站开发 入门教程

    这个系列的教程由表单开始写,因为表单可以把数据库和web 之间的交互表现得很明显.提交表单 ,数据库记录注册信息. 本教程属于基础教程.大神请略过.        对于php和mysql之间的稳固性很 ...

  5. USB Key插入和移除监控

    近期在做USB Key插入和移除监控,已经做到了插入和移除USB Key时,程序能够及时感应到. 如下为源代码: private void Form1_Load(object sender, Even ...

  6. IEnumerable,ICollection,IList,List区别

    做C#的同学们,都知道,一类只能有一个继承类,但可以实现多个接口.这句话就告诉我们:IEnumerable,ICollection,IList,List区别了 首先我看看 IEnumerable: / ...

  7. UIStackView 简单使用

    UIStackView提供了一个高效的接口用于平铺一行或一列的视图组合.对于嵌入到StackView的视图,你不用再添加自动布局的约束了.Stack View管理这些子视图的布局,并帮你自动布局约束. ...

  8. [原博客] POJ 1740 A New Stone Game

    题目链接题意:有n堆石子,两人轮流操作,每次每个人可以从一堆中拿走若干个扔掉(必须),并且可以从中拿走一些分到别的有石子的堆里(可选),当一个人不能拿时这个人输.给定状态,问是否先手必胜. 我们参考普 ...

  9. 探索React生态圈

    原文地址:http://www.csdn.net/article/2015-08-04/2825370-react 2004年,对于前端社区来说,是里程碑式的一年.Gmail横空出世,它带来基于前端渲 ...

  10. 我是如何实用:before :after

    本文地址http://www.cnblogs.com/Bond/p/3972854.html 最近一直做移动端,没和IE6打交道了,瞬间感觉世界变美好了.移动端虽然还是各种坑,但是比起修复IE6那还是 ...