POJ 3225 Help with Intervals --线段树区间操作
题意:给你一些区间操作,让你输出最后得出的区间。
解法:区间操作的经典题,借鉴了网上的倍增算法,每次将区间乘以2,然后根据区间开闭情况做微调,这样可以有效处理开闭区间问题。
线段树维护两个值: cov 和 rev ,一个是覆盖标记,0表示此区间被0覆盖,1表示被1覆盖,-1表示未被覆盖, rev为反转标记,rev = 1表示反转,0表示不翻转
所以集合操作可以化为如下区间操作:
U l r: 把区间[l,r]覆盖成1
I l r: 把[0,l)(r,MAX]覆盖成0
D l r: 把区间[l,r]覆盖成0
C l r: 把[0,l)(r,MAX]覆盖成0 , 且[l,r]区间0/1互换
S l r: [l,r]区间0/1互换
重点在于pushdown函数以及边界处理。
代码:
#include <iostream>
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
#define N (65536*2) struct Tree
{
int cov,rev; //cov -1 rev 0
}tree[*N]; struct ANS
{
char L,R;
int A,B;
}ans[N+];
int cnt; void build(int l,int r,int rt)
{
tree[rt].cov = ;
tree[rt].rev = ;
if(l == r) return;
int mid = (l+r)/;
build(l,mid,*rt);
build(mid+,r,*rt+);
} void pushdown(int l,int r,int rt)
{
if(tree[rt].cov != -)
{
tree[*rt].cov = tree[*rt+].cov = tree[rt].cov;
tree[*rt].rev = tree[*rt+].rev = ;
tree[rt].cov = -;
}
if(tree[rt].rev)
{
if(tree[*rt].cov != -)
tree[*rt].cov ^= ;
else
tree[*rt].rev ^= ; if(tree[*rt+].cov != -)
tree[*rt+].cov ^= ;
else
tree[*rt+].rev ^= ;
tree[rt].rev = ;
}
} void update(int l,int r,int aa,int bb,int op,int rt)
{
if(aa > bb || aa < ) return; //必须要加,否则会RE
if(aa <= l && bb >= r)
{
if(op != ) //cover to 0/1
{
tree[rt].cov = op;
tree[rt].rev = ;
}
else //op == 2 reverse
{
if(tree[rt].cov != -)
tree[rt].cov ^= ;
else
tree[rt].rev ^= ;
}
return;
}
pushdown(l,r,rt);
int mid = (l+r)/;
if(aa <= mid)
update(l,mid,aa,bb,op,*rt);
if(bb > mid)
update(mid+,r,aa,bb,op,*rt+);
} void query(int l,int r,int rt)
{
if(tree[rt].cov == )
{
ans[cnt].L = (l%==)?'(':'[';
ans[cnt].A = l/;
ans[cnt].R = (r%==)?')':']';
ans[cnt].B = (r+)/;
cnt++;
}
else if(tree[rt].cov == ) return;
else
{
pushdown(l,r,rt);
int mid = (l+r)/;
query(l,mid,*rt);
query(mid+,r,*rt+);
}
} void print()
{
char nowl,nowr;
int nowA,nowB;
if(cnt == )
puts("empty set");
else
{
nowl = ans[].L;
nowr = ans[].R;
nowA = ans[].A;
nowB = ans[].B;
for(int i=;i<cnt;i++)
{
if(ans[i].A == nowB && (nowr == ']' || ans[i].L == '['))
{
nowB = ans[i].B;
nowr = ans[i].R;
}
else
{
printf("%c%d,%d%c ",nowl,nowA,nowB,nowr);
nowl = ans[i].L;
nowr = ans[i].R;
nowA = ans[i].A;
nowB = ans[i].B;
}
}
printf("%c%d,%d%c\n",nowl,nowA,nowB,nowr);
}
} int main()
{
int a,b;
char L,R,op;
int n = *;
build(,n,);
while(scanf("%c %c%d,%d%c\n",&op,&L,&a,&b,&R)!=EOF) // '\n' 务必要加
{
a = *a; if(L == '(') a++;
b = *b; if(R == ')') b--;
if(a > b || a < ) continue;
if(op == 'U') //并集
update(,n,a,b,,);
else if(op == 'I')
{
update(,n,,a-,,);
update(,n,b+,n,,);
}
else if(op == 'D')
update(,n,a,b,,);
else if(op == 'C')
{
update(,n,,a-,,);
update(,n,b+,n,,);
update(,n,a,b,,);
}
else
update(,n,a,b,,);
}
cnt = ;
query(,n,);
print();
return ;
}
参考文章: http://my.oschina.net/llmm/blog/124256
POJ 3225 Help with Intervals --线段树区间操作的更多相关文章
- poj 3225 Help with Intervals(线段树,区间更新)
Help with Intervals Time Limit: 6000MS Memory Limit: 131072K Total Submissions: 12474 Accepted: ...
- (中等) POJ 3225 Help with Intervals , 线段树+集合。
Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While ...
- POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化)
POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化) 题意分析 贴海报,新的海报能覆盖在旧的海报上面,最后贴完了,求问能看见几张海报. 最多有10000张海报,海报 ...
- POJ 2528 Mayor's posters (线段树区间更新+离散化)
题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...
- POJ 2528 ——Mayor's posters(线段树+区间操作)
Time limit 1000 ms Memory limit 65536 kB Description The citizens of Bytetown, AB, could not stand t ...
- Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...
- 线段树(区间操作) POJ 3325 Help with Intervals
题目传送门 题意:四种集合的操作,对应区间的01,问最后存在集合存在的区间. 分析:U T [l, r]填充1; I T [0, l), (r, N]填充0; D T [l, r]填充0; C T[0 ...
- poj 2528 Mayor's posters 线段树区间更新
Mayor's posters Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=2528 Descript ...
- hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】
Tunnel Warfare Time Limit: 4000/2000 MS ...
随机推荐
- 优化磁盘I/O
管理I/O,避免过度地寻道可以让硬盘更快.顺序I/O和随机I/O之间的性能差异随便就可以达到40:1,可能更多.这在数据库服务器中尤其重要,因为数据库的日志是以顺序格式写的.选择合适的硬件,合理地配置 ...
- Windows工作集内存
Windows任务管理器默认情况下,“内存(私人工作集)”列处于选中状态. 私人工作集是工作集的一个子集,它是描述每个进程所使用的内存数量的技术术语.私人工作集专门描述了某个进程正在使用的且无法与其他 ...
- Java 进程占用 VIRT 虚拟内存超高的问题研究
1. 现象 最近发现线上机器 java 8 进程的 VIRT 虚拟内存使用达到了 50G+,如下图所示: 2. 不管用的 -Xmx 首先第一想到的当然使用 java 的 -Xmx 去限制堆的使用.但是 ...
- echarts 地图图
效果如下图: 1.下载echarts对应包: http://echarts.baidu.com/ 2.前端页面: <!DOCTYPE html> <html xmlns=" ...
- ABAP中使用浏览器打开网页
在SAP ABAP中可以在Screen中嵌入Html control打开网页,也可以通过调用本地的IE浏览器打开. 1.在Screen中嵌入Html control的例子,在系统中有,se38:SAP ...
- Docker: 解决Docker无法在电信网络中访问外网
在电信网络中,Docker在build和run时会无法访问外网,原因是docker的默认dns地址是8.8.8.8,由于众所周知的原因,我们需要改写这个地址,方法如下: 修改/etc/sysconfi ...
- JAVA----编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符
package com.pb.demo.packclass.demo1; import java.util.HashSet; /** * 编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符 ...
- const,static,extern简介(重要)
一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 编译时刻:宏是预编译(编译之前处理),const是编译 ...
- JMeter源码集成到Eclipse
由于JMeter纯Java开发,界面也是基于Swing或AWT搞出来的,所以想更深层次的去了解这款工具或对于想了解JMeter插件开发或二次开发的童鞋们来说,读读JMeter的源码估计是必不可少的,所 ...
- Erlang 的新数据结构 map 浅析
更新:文中示例代码直接从Joe的新版 Erlang 书中摘抄而来,其中模式匹配的代码有错误,现已纠正.应该用 := 匹配字段,而不是 => . 即将发布的 Erlang 17 最大变化之一包括新 ...