题目链接: http://poj.org/problem?id=3225

题意: 初始给一个全局为 0~65536 的区间  s, 然后不断地对区间 s 进行 并, 交, 差, 相对差等运算, 输出最终结果;

思路: 很显然是线段树区间操作的路子, 但要 AC 还需细细斟酌;

下面一段题解摘自博客: http://blog.csdn.net/metalseed/article/details/8039326

我们一个一个操作来分析:(用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互换

成段覆盖的操作很简单,比较特殊的就是区间0/1互换这个操作,我们可以称之为异或操作
很明显我们可以知道这个性质:当一个区间被覆盖后,不管之前有没有异或标记都没有意义了
所以当一个节点得到覆盖标记时把异或标记清空
而当一个节点得到异或标记的时候,先判断覆盖标记,如果是0或1,直接改变一下覆盖标记,不然的话改变异或标记

开区间闭区间只要数字乘以2就可以处理(偶数表示端点,奇数表示两端点间的区间)
线段树功能:update:成段替换,区间异或 query:简单hash

代码:

 #include <stdio.h>
#include <iostream>
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std; const int MAXN = << ;
bool hash[MAXN + ];//hash标记答案
int cover[MAXN << ], Xor[MAXN << ];//cover为区间的0/1状态, Xor为区间的转换状态 void Fxor(int rt){//更新区间转换状态
if(cover[rt] != -) cover[rt] ^= ;//当前区间标记为0 或 1
else Xor[rt] ^= ;//当前区间既有0, 又有 -1 的情况
} void push_down(int rt){//将标记推到下一层
if(cover[rt] != -){
cover[rt << ] = cover[rt << | ] = cover[rt];
Xor[rt << ] = Xor[rt << | ] = ;//清空标记
cover[rt] = -;
}
if(Xor[rt]){
Fxor(rt << );
Fxor(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'){
cover[rt] = ;
Xor[rt] = ;
}else if(op == 'D'){
cover[rt] = ;
Xor[rt] = ;
}else if(op == 'C' || op == 'S') Fxor(rt);
return;
}
push_down(rt);//向下更新
int mid = (l + r) >> ;
if(L <= mid) update(op, L, R, lson);
else if(op == 'I' || op == 'C'){
Xor[rt << ] = cover[rt << ] = ;//当op为I或C时,若当前[l, r]不在[L, R]内,则清空
}
if(R > mid) update(op, L, R, rson);
else if(op == 'I' || op == 'C'){
Xor[rt << | ] = cover[rt << | ] = ;
}
} void query(int l, int r, int rt){
if(cover[rt] == ){
for(int i = l; i <= r; i++){
hash[i] = true;
}
return;
}else if(cover[rt] == ) return;
if(l == r) return;
push_down(rt);
int mid = (l + r) >> ;
query(lson);
query(rson);
} int main(void){
int l, r;
char op, a, b;
while(~scanf("%c %c%d,%d%c", &op, &a, &l, &r, &b)){
getchar();
l <<= ;
r <<= ;
if(a == '(') l++;
if(b == ')') r--;
if(l > r){//输入区间为 (1, 1)这样的情况
if(op == 'I' || op == 'C') cover[] = Xor[] = ;
}else update(op, l, r, , MAXN, );
}
query(, MAXN, );
bool flag = false;
int s = -, e;//记录当前区间开头和结尾位置
for(int i = ; i <= MAXN; i ++){
if(hash[i]){
if(s == -) s = i;
e = i;
}else{
if(s != -){
if(flag) printf(" ");
flag = true;
printf("%c%d,%d%c", s& ? '(' : '[', s>>, (e + )>>, e& ? ')' : ']');
s = -;
}
}
}
if(!flag) printf("empty set");
puts("");
return ;
}

poj3225(线段树区间更新&hash)的更多相关文章

  1. HDU 1556 Color the ball(线段树区间更新)

    Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...

  2. hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新

    #1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...

  3. HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...

  4. HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...

  5. HDU 1698 线段树 区间更新求和

    一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...

  6. POJ-2528 Mayor's posters (线段树区间更新+离散化)

    题目分析:线段树区间更新+离散化 代码如下: # include<iostream> # include<cstdio> # include<queue> # in ...

  7. ZOJ 1610 Count the Colors (线段树区间更新)

    题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头 ...

  8. POJ 2528 Mayor's posters (线段树区间更新+离散化)

    题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...

  9. HDU5039--Hilarity DFS序+线段树区间更新 14年北京网络赛

    题意:n个点的树,每个条边权值为0或者1, q次操作 Q 路径边权抑或和为1的点对数, (u, v)(v, u)算2个. M i修改第i条边的权值 如果是0则变成1, 否则变成0 作法: 我们可以求出 ...

随机推荐

  1. Python实现简易HTTP服务器

    一.Python3 搭建简易HTTP服务器 python -m http.server 浏览器访问:http://localhost:8000 Python3 cgiserver python -m  ...

  2. Oracle | PL/SQL Check约束用法详解

    1. 目标 实例讲解在Oracle中如何使用CHECK约束(创建.启用.禁用和删除) 2. 什么是Check约束? CHECK约束指在表的列中增加额外的限制条件. 注: CHECK约束不能在VIEW中 ...

  3. ruby 正则表达式

    Ruby学习笔记-正则表达式 Posted on 2011-11-29 17:55 Glen He 阅读(4998) 评论(0) 编辑 收藏 1.创建正则表达式 a) reg1 = /^[a-z]*$ ...

  4. Linux线程的几种结束方式

    Linux创建线程使用 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) ...

  5. g2o的一般过程

    1.自己定义顶点类.边类或者用已经有的.1.1定义顶点例子class CurveFittingVertex: public g2o::BaseVertex<3, Eigen::Vector3d& ...

  6. pip 安装模块报错解决

    系统版本 ubuntu  Kylin 16.04 LTS 报错1:安装pip3 安装 Django 总是提示time out,无法安装. 改用国内源: 豆瓣源: sudo pip3 install - ...

  7. 批量导入oracle 的sql脚本

    以下为脚本样例:execute.sql,在PL/sql的command窗口或sqlplus中执行:@目录/execute.sql (以下“目录”需要替换为实际sql所在目录) --执行前需要在目录下新 ...

  8. smokeping高级配置

    摘自: http://mayulin.blog.51cto.com/1628315/514367 自定义报警 http://www.cnblogs.com/thatsit/p/6395506.html

  9. OpenCV——PS滤镜算法之 球面化 (凹陷效果)

    // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...

  10. ZOJ1905Power Strings (KMP||后缀数组+RMQ求循环节)

    Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc&quo ...