poj3225(线段树区间更新&hash)
题目链接: 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)的更多相关文章
- HDU 1556 Color the ball(线段树区间更新)
Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...
- hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新
#1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...
- HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...
- HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...
- HDU 1698 线段树 区间更新求和
一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...
- POJ-2528 Mayor's posters (线段树区间更新+离散化)
题目分析:线段树区间更新+离散化 代码如下: # include<iostream> # include<cstdio> # include<queue> # in ...
- ZOJ 1610 Count the Colors (线段树区间更新)
题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头 ...
- POJ 2528 Mayor's posters (线段树区间更新+离散化)
题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...
- HDU5039--Hilarity DFS序+线段树区间更新 14年北京网络赛
题意:n个点的树,每个条边权值为0或者1, q次操作 Q 路径边权抑或和为1的点对数, (u, v)(v, u)算2个. M i修改第i条边的权值 如果是0则变成1, 否则变成0 作法: 我们可以求出 ...
随机推荐
- 怎样拆分View Controller进而实现轻量级的View Controller[UIKit]
參考文章来自objcio站点 为什么要编写轻量级的View Controller?? 1.作为iOS项目中最大的文件,ViewControllers中的代码复用率差点儿是最低的 2.重量级的V ...
- MySQL——sql语句的执行顺序
#核心知识点: 书写顺序:where——>group by——>having——>order by——>limit 许多时候在书写一些复杂的sql语句的时候,尤其是在渐进式推导 ...
- python -- redis连接与使用
前面我们简单介绍了redis nosql数据库,现在我们在python里面来使用redis. 一.python连接redis 在python中,要操作redis,目前主要是通过一个python-red ...
- ZOJ - 3861 Valid Pattern Lock 【全排列】
题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3861 思路 先生成全排列,然后判断哪些情况不符合的,剔除就好了 ...
- perl之创建临时文件夹遇到同名文件该咋办
当你在目录下进行一系列操作时,若要创建许多文件或者修改文件,可能会遇到许多麻烦的事.所以呢,新建一个文件夹,然后在这个文件夹下新建文件或者修改文件.假设,你的代码要在一个目录下新建一个文件夹,名为Tm ...
- 基础 PHP 语法
PHP 脚本在服务器上执行,然后向浏览器发送回纯 HTML 结果. 基础 PHP 语法 PHP 脚本可放置于文档中的任何位置. PHP 脚本以 <?php 开头,以 ?> 结尾: < ...
- 深入浅出,JS原型链的工作原理
前言:原型链,即原型链条.它是由原型.原型的原型.原型的原型的原型...这一规则组合成的,经常被应用于继承. 原型的作用在JS中,每个对象都有自己的原型.当我们访问对象的属性和方法时,JS会先访问对象 ...
- Quartz的misfire理解
misfire用于Trigger触发时,线程池中没有可用的线程或者调度器关闭了,此时这个Trigger变为misfire.当下次调度器启动或者有可以线程时,会检查处于misfire状态的Trigger ...
- poj 3041 Asteroids(二分图 *【矩阵实现】【最小点覆盖==最大匹配数】)
Asteroids Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16379 Accepted: 8930 Descri ...
- Java多线程编程核心 - 对象及变量的并发访问
1.什么是“线程安全”与“非线程安全”? “非线程安全”会在多个线程对同一对象总的实例变量进行并发访问时发生,产生的后果是“脏读”,也就是取到的数据其实是被更改过的. “线程安全”是以获得的实例变量的 ...