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 ...
随机推荐
- 清除浮动after
.clearf{display: inline-block;} .clearf:after { content: "."; display: block; height:; cle ...
- HTML · 图片热点,网页划区,拼接,表单
图片热点: 规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可以完成跳转的效果. 网页划区: 在一个网页里,规划出一个区域用来展示另一个网页的内容. 网页的拼接: 在一个网络页面内,规划出多 ...
- 再说Play!framework http://hsfgo.iteye.com/blog/806974
这篇帖子的内容我本来想发到 http://www.iteye.com/topic/806660这里的主贴里去的,想挽回被隐藏的命运,但我写完本贴的内容,却发现为时已晚.好吧,我承认,上一个贴的标题容易 ...
- OC正则表达式的使用
OC中一般正则表达式的使用方法为2步 1.创建一个正则表达式对象 2.利用正则表达式来测试对应的字符串 例如 NSString *checkString = @"a34sd231" ...
- 关于UI资源获取资源的好的网站
前言:和我一样喜欢UI的一定喜欢这里的内容. 下面是关于sketch资源获取网页,点击图片就能进入: 连接是:https://github.com/JakeLin 居然意外百度到Sketch中国,还提 ...
- Objective-C之代理设计模式小实例
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- Swift 中的函数(下)
学习来自<极客学院:Swift中的函数> 工具:Xcode6.4 直接上基础的示例代码,多敲多体会就会有收获:百看不如一敲,一敲就会 import Foundation /******** ...
- mysql给数据库授权 GRANT ALL PRIVILEGES ON
mysql> grant 权限1,权限2,…权限n on 数据库名称.表名称 to 用户名@用户地址 identified by ‘连接口令’; show grants for mustang@ ...
- Effective Java 60 Favor the use of standard exceptions
Benefits to reuse preexisting exceptions It makes your API easier to learn and use. Programs using y ...
- http://runjs.cn/
http://runjs.cn/ RunJS - 在线编辑.展示.分享.交流你的 JavaScript 代码