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 ...
随机推荐
- 【洛谷 p3374】模板-树状数组 1(数据结构)
题目:已知一个数列,你需要进行下面两种操作:1.将某一个数加上x:2.求出某区间每一个数的和. 解法:树状数组求前缀和. #include<cstdio> #include<cstd ...
- 记录php日志
1.记录PHP错误日志 display_errors与log_errors的区别 display_errors 错误回显,一般常用于开发模式,但是很多应用在正式环境中也忘记了关闭此选项.错误回显可以暴 ...
- ASP.NET WebAPI 14 仿写Filter管道
WebAPI中有设计了几种管道(Channel),大概如下:HttpMessageHandler,ActionFilter管道,ExceptionFilter管道.在三种管道中HttpMessageH ...
- 单例(Singleton pattern)模式的七种写法
转载请注明出处:http://www.cnblogs.com/smbk/ One: public class Singleton { private static Singleton instance ...
- HTML <map> 标签-创建带有可点击区域的图像映射
定义和用法 定义一个客户端图像映射.图像映射(image-map)指带有可点击区域的一幅图像. 所有主流浏览器都支持 <map> 标签. 注释:area 元素永远嵌套在 map 元素内部. ...
- 对抗静态分析——运行时修复dex
对抗静态分析——运行时修复dex 本文来源:i春秋社区-分享你的技术,为安全加点温度 零.写在前面 这个系列本来题目想写对抗反编译,可是想想对抗反编译的这个范围有点大,总结如下 灵魂作图 ...
- Atitit.电脑图片与拍摄图片的分别
Atitit.电脑图片与拍摄图片的分别 1. Extname都是jpg的..1 1.1. 数码照片的Exif信息, 1 1.2. 是否有人脸1 1.3. 是否skin图1 1.4. 是否大面积色素单一 ...
- SQL Server 分组 去除从复列
下面先来看看例子: table表 字段1 字段2 id name 1 a 2 b 3 c 4 c 5 ...
- JavaWeb开发必过关-Servlet学习(一)
一.什么是Servlet servlet其实是一个小程序,它是运行在服务器上的,一个servlet就是一个Java类,可以通过"请求-响应"编程模型来访问这个驻留在服务器内存的Se ...
- JAVA基础学习day13--String、StringBuilder与StringBuffer与包装类
一.String 1.1.String String 类是final修饰的,是顶级类,不可被继承 String 类代表字符串.Java 程序中的所有字符串字面值(如 "abc" ) ...