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. OpenJudge/Poj 1631 Bridging signals

    1.链接地址: http://poj.org/problem?id=1631 http://bailian.openjudge.cn/practice/1631 2.题目: Bridging sign ...

  2. 日期字符串转换为NSDate

    // 纯数字日期 NSString *str1 = "; // 日期字符串 NSString *str2 = @"2015/05/12 10:22:01"; // 带时区 ...

  3. 无刷新分页 Ajax,JQuery,Json

    1.数据库设计 字段:Id(int) , Msg(varchar(MAX)) , PostDate(datetime) 2.自定义SQL查询方法(强类型DataSet) //SelectCount() ...

  4. datareader 和dataset 区别

    ADO.NET2.0提供了两个用于检索关系数据的对象:DataSet和DataReader.并且这两个对象都可以将检索的关系数据存储在内存中.在软件开发过程中经常用到这两个控件,由于这两个控件在使用和 ...

  5. IE6下解决select层级高的问题

    div在IE6下无法遮盖select,原因是在IE6下,浏览器将select元素视为窗口级元素,这时div或者其它的普通元素无论z-index设置的多高都是无法遮住select元素的. 解决方法有三种 ...

  6. 织梦DedeCMS网站地图模板

    亲和百度蜘蛛,分页多层次特色,织梦系统最好用的网站地图! 用 DedeCMS(织梦) 系统搭建的网站多数都是以优化为主要目标的网站类型,既然是优化站 SEO 手段就离不开为网站设置网站地图.可是 De ...

  7. mysql开启日志记录慢查询

    1.查看mysql配置 2.利用set (variables)命令设置变量 set global log_slow_queries = ON;/*(必须带上global)*/ set global s ...

  8. python入门 第二天笔记

    程序主文件标志if __name__=="__main__": 在程序执行python 1.py 时候 程序1.py __name__ 为 main调用其他文件是,__name__ ...

  9. IEnumerable,ICollection,IList,List区别

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

  10. EntityFramework动态组合多排序字段

    前言:在使用EF当中,肯定会遇到动态查询的需求,建立一个公共调用的动态组合表达式查询也是必不可少的,以下是建立动态组合多排序字段做个记录,供以后调用 1.建立一个结构,用于多个排序字段组合,这个结构体 ...