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 作法: 我们可以求出 ...
随机推荐
- 用c++后缀自动机实现最大公共字符串算法,并封装成Python库
后缀自动机的C++代码转自https://e-maxx.ru/algo/suffix_automata,其余封装为自写. 在C++文件同级目录建立setup.py文件,代码如下: # !/usr/bi ...
- API的理解和使用——全局命令
全局命令 命令 功能 set 创建键值对 keys 遍历查看所有键 exists 判断一个键是否存在,1存在,0不存在 dbsize 当前数据库中有多少个键 del 删除一个或多个键 expire 设 ...
- spring-boot-starter-parent
在官方文档的第三部分的13块讲述了引用的管理,官方推荐的是使用Maven和Gradle. 我一直在用的是maven,而且使用maven有些优势–spring-boot-starter-parent,这 ...
- Java多线程系列 基础篇02 线程的创建和运行
1.线程创建的方式常用有两种 1. 继承 Thread 类创建线程 2. 实现 Runnable 接口创建线程 2.Thread 和 Runnable的区别 Thread和Runnable的相同点:都 ...
- 现代JS中的流程控制:详解Callbacks 、Promises 、Async/Await
JavaScript经常声称是_异步_.那是什么意思?它如何影响发展?近年来这种方法有何变化? 请思考以下代码: result1 = doSomething1(); result2 = doSomet ...
- MVC+Ext.net零基础学习记录(五)
继MVC+Ext.net零基础学习记录(四),在后面我在既有的项目上又添加了一个子项目,还用前面提到的方法,进行主项目中引用DLL,然后子项目中生成事件中使用mkdir 进行拷贝 发现一个下午就总是报 ...
- git创建与管理远程分支【转】
本文转载自:http://blog.chinaunix.net/uid-9398085-id-3164754.html git创建与管理远程分支 1.远程分支就是本地分支push到服务器上的时候产生的 ...
- POJ2104 K-th Number —— 静态区间第k小
题目链接:http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Sub ...
- 利用javascript动态向网页中添加表格
效果图如下: 以下是代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...
- smokeping再次部署遇到的问题记录
问题1: Can't locate Sys/Syslog.pm in @INC (@INC contains: /opt/smokeping_workspace/thirdparty/lib/perl ...