POJ 3225 Help with Intervals
2015-09-17 23:23
369 查看
题目链接:http://poj.org/problem?id=3225&lang=zh-CN&change=true
题意:对一个区间进行5种操作,问最后覆盖区间
1.U T 当前区间并上区间T
2. I T 当前区间交上区间T
3.D T 将当前区间和区间T的交去掉
4.C T 将T区间中与当前区间的交去掉
5.S T DT并上CT
思路:可以想到每种操作就是对区间更新,和之前的题目一样使用lazy标记就可以做到,lazy标志不会一直重叠,区间就只有3种情况:被覆盖(lazy==1).没有被覆盖(lazy==0),以及部分覆盖(lazy==-1),不一样的地方某些操作会将区间覆盖翻转(覆盖变成未覆盖,未覆盖变成覆盖),需要用到翻转标记,当lazy标记下传的时候根据翻转标记的奇偶性进行改变;还有注意的是D(3,4)一类的普通的线段树进行更新查询出现[l,2]和[5,r]的情况,和答案[l,3)和(4,r]不一样,也就是说我们没有办法判断开闭区间,这个时候我们要把l和r乘2,如果是(l,r)的话,l++以及r--,最后在判断奇偶性就可以知道是开闭区间了……
将5种操作翻译一下:
1. 将T区间覆盖
2. 将T以外的地方清空
3. 将T区间清空
4.将T区间以外的地方清空,T区间内原来覆盖的地方覆盖,覆盖的地方清空
5.操作3与操作4的并,也就是T区间进行翻转
题意:对一个区间进行5种操作,问最后覆盖区间
1.U T 当前区间并上区间T
2. I T 当前区间交上区间T
3.D T 将当前区间和区间T的交去掉
4.C T 将T区间中与当前区间的交去掉
5.S T DT并上CT
思路:可以想到每种操作就是对区间更新,和之前的题目一样使用lazy标记就可以做到,lazy标志不会一直重叠,区间就只有3种情况:被覆盖(lazy==1).没有被覆盖(lazy==0),以及部分覆盖(lazy==-1),不一样的地方某些操作会将区间覆盖翻转(覆盖变成未覆盖,未覆盖变成覆盖),需要用到翻转标记,当lazy标记下传的时候根据翻转标记的奇偶性进行改变;还有注意的是D(3,4)一类的普通的线段树进行更新查询出现[l,2]和[5,r]的情况,和答案[l,3)和(4,r]不一样,也就是说我们没有办法判断开闭区间,这个时候我们要把l和r乘2,如果是(l,r)的话,l++以及r--,最后在判断奇偶性就可以知道是开闭区间了……
将5种操作翻译一下:
1. 将T区间覆盖
2. 将T以外的地方清空
3. 将T区间清空
4.将T区间以外的地方清空,T区间内原来覆盖的地方覆盖,覆盖的地方清空
5.操作3与操作4的并,也就是T区间进行翻转
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define maxn 65835*2 using namespace std; struct Tree { int l,r; }tree[maxn*4]; int lazy[maxn*4],turn[maxn*4],res_l[maxn],res_r[maxn]; int cnt=0; void build(int root,int l,int r) { tree[root].l=l; tree[root].r=r; if (l==r) return; int mid=(l+r)>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r); } void pushdown(int root) { if (lazy[root]!=-1) { if (turn[root]%2==1) lazy[root]=!lazy[root]; lazy[root<<1]=lazy[root<<1|1]=lazy[root]; turn[root<<1]=turn[root<<1|1]=turn[root]=0; lazy[root]=-1; } if (turn[root]%2==1) { turn[root<<1]++; turn[root<<1|1]++; turn[root]=0; } } void update(int root,int l,int r,int val,int k) { if (tree[root].l>=l && tree[root].r<=r) { if (k==1) { lazy[root]=val; turn[root]=0; } else turn[root]++; return; } pushdown(root); int mid=(tree[root].l+tree[root].r)>>1; if (l<=mid) update(root<<1,l,r,val,k); if (r>mid) update(root<<1|1,l,r,val,k); } void que(int root,int l,int r) { if (lazy[root]!=-1) { if (turn[root]%2==1) {//cout<<":"<<lazy[root]<<endl; lazy[root]=!lazy[root]; turn[root]=0; } if (lazy[root]==1) {//cout<<tree[root].l<<":"<<":"<<tree[root].r<<endl; res_l[cnt]=tree[root].l; res_r[cnt]=tree[root].r; cnt++; } return; } if (tree[root].l==tree[root].r) return; pushdown(root); int mid=(tree[root].l+tree[root].r)>>1; if (l<=mid) que(root<<1,l,r); if (r>mid) que(root<<1|1,l,r); } int main() { char op,ll,rr; int l,r; build(1,0,maxn-1); memset(lazy,0,sizeof(lazy)); memset(turn,0,sizeof(turn)); cnt=0; while (scanf("%c %c%d,%d%c",&op,&ll,&l,&r,&rr)!=EOF) { l*=2; r*=2; if (ll=='(') l++; if (rr==')') r--; if (op=='U') {//cout<<l<<":"<<r<<endl; if (l<=r) update(1,l,r,1,1); } else if (op=='I') { if (l>0) update(1,0,l-1,0,1); update(1,r+1,maxn-1,0,1); } else if (op=='D') { if (l<=r) update(1,l,r,0,1); } else if (op=='C') { if (l>0) update(1,0,l-1,0,1); update(1,r+1,maxn-1,0,1); if (l<=r) update(1,l,r,0,0); } else if (op=='S') { if (l<=r) update(1,l,r,0,0); } getchar(); } que(1,0,maxn-1); if (cnt!=0) { for (int i=0;i<cnt;i++) { int tem=i; while (i<cnt-1 && res_r[i]==res_l[i+1]-1) i++; int st=res_l[tem],ed=res_r[i]; if (st%2==0) printf("[%d,",st/2); else printf("(%d,",st/2); if (ed%2==0) printf("%d] ",ed/2); else printf("%d) ",(ed+1)/2); } } else printf("empty set"); printf("\n"); }
相关文章推荐
- Android图片资源命名规范
- [转]MySQL 高可用架构在业务层面的应用分析
- 大学学习日志
- ORMLite框架入门用法
- [CareerCup] 9.2 Robot Moving 机器人移动
- Largest Rectangle in Histogram
- 每天一个linux命令(8):ls命令
- hadoop1.x中IPC协议
- Android基础_学习Fragment时候出现的一些错误[博客园]
- day09_抽象类
- Android context 向上转型与继承
- 编程思想 thisP84 和内部类 匿名类 Android ACTIVITY 跳转
- Think in Java 实例变量的初始化
- Think in Java IO流的 字节流部分
- Think in Java 构造函数_继承_super()_android_Dialog()_为何有些类没有构造函数自己体悟
- Think in Java 笔记_Chapter12_1_Exception基础_继承和RuntimeException处理1
- Think in Java 笔记_Chapter12_1_Exception基础_异常处理2
- cocos2dx 数据内存管理----RefPtr智能指针
- Opencv漫水填充-鼠标、滚动条
- 电表常用