题目链接: 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. http://blog.csdn.net/wh211212/article/details/53005321

    http://blog.csdn.net/wh211212/article/details/53005321

  2. pm2 的使用

    pm2.json 代码如下 [{ "name" : "dingtalk-mobile", "script" : "app.js&q ...

  3. Java for LeetCode 129 Sum Root to Leaf Numbers

    Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number ...

  4. nginx负载均衡设置

    在nginx的配置文件[./conf/nginx.conf]中加入: upstream test.balance123.com { server 192.168.1.223:80; server 19 ...

  5. EASYARM-IMX283 编译uboot和uImage

    本文是按照IMX283配套光盘的流程重新编译uboot和uImage将光盘中的gcc-4.4.4-glibc-2.11.1-multilib-1.0_EasyARM-iMX283.tar.bz2 解压 ...

  6. <JAVA8新增内容>关于匿名内部集合和lambda表达式

    要想说清楚JAVA中的Lambda表达式,必须想讲一下匿名内部类来帮助理解本质. 一.匿名内部类 匿名内部类适合创建那种只需要一次使用的类,例如前面介绍命令模式时所需要的Command对象,匿名内部类 ...

  7. Struts2 小例子 --第二弹

    struts-2.5.14.1-all.zip  下载后文件夹说明 apps:war格式的例子文件 lib:引用jar包文件 src:源码文件 docs:帮助文档 小例子: 1.创建web工程:str ...

  8. 分享知识-快乐自己:自定义struts2类型转换的全局与局部错误信息。

    遇到类型转换错误的时候(也就是说不能进行类型转换),struts2框架自动生成一条错误信息,并且将该错误信息放到addFieldError里面.我们可以通过配置文件来替换这条由struts2自动生成的 ...

  9. 使用chrome的F12开发人员工具进行网页前端性能测试

    用chrome访问被测网站,定位到你要测试的动作所在页面或被测页面的前一页.按F12调出开发人员工具,其它的功能我就不介绍了,直接切换到性能选项卡Profiles. 点击start,生成ProFile ...

  10. 远程调用appium server

    例如:我有两台电脑A(192.168.112.10)和B(192.168.112.11),那我怎么能在A执行本地脚本,但是使用B上的server呢?   查看appium连接appium服务并开启一个 ...