POJ3225 Help with Intervals 线段树区间更新
2015-10-06 16:58
239 查看
题目链接:http://poj.org/problem?id=3225
题目大意:给出区间操作交,并,补,差,和异或,问你在n次操作之后的区间是什么。
分析:这里我们用区间倍增来解决区间的开闭问题,然后对于每一种操作,我们用01表示该段区间是否存在。
实现代码如下:
题目大意:给出区间操作交,并,补,差,和异或,问你在n次操作之后的区间是什么。
分析:这里我们用区间倍增来解决区间的开闭问题,然后对于每一种操作,我们用01表示该段区间是否存在。
实现代码如下:
/* 倍增区间来解决区间的开闭问题,对于区间操作: 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互换 */ #include <cstdio> #include <cstring> using namespace std; const int M=65536*2; struct segment { int l,r; int tag; //纪录区间点的值。-1表示该区间为杂色 bool rev; //标记该区间是否翻转 int mid() { return (l+r)>>1; } }tree[M<<2]; void build(int rt,int l,int r) { tree[rt].l=l; tree[rt].r=r; tree[rt].tag=0; tree[rt].rev=false; if(l==r) return ; int m=tree[rt].mid(); build(rt<<1,l,m); build(rt<<1|1,m+1,r); } void pushdown(int rt) { if(tree[rt].l==tree[rt].r) { if(tree[rt].rev) //需要翻转的话就翻转 { tree[rt].rev=false; tree[rt].tag^=1; } return ; } if(tree[rt].tag!=-1) //该区间为纯色 { if(tree[rt].rev) tree[rt].tag^=1; tree[rt<<1].tag=tree[rt<<1|1].tag=tree[rt].tag; tree[rt].tag=-1; tree[rt<<1].rev=tree[rt<<1|1].rev=tree[rt].rev=false; } if(tree[rt].rev) { tree[rt].rev=false; if(tree[rt<<1].tag==-1) tree[rt<<1].rev^=1; else tree[rt<<1].tag^=1; if(tree[rt<<1|1].tag==-1) tree[rt<<1|1].rev^=1; else tree[rt<<1|1].tag^=1; } } void update(int rt,int l,int r,int v) { if(l>r) return ; if(tree[rt].l==l&&tree[rt].r==r) { if(v<2) //赋值操作 { tree[rt].rev=false; tree[rt].tag=v; } else //翻转操作 { if(tree[rt].tag!=-1) //区间为纯色,直接翻转即可 tree[rt].tag^=1; else tree[rt].rev^=1; //翻转次数+1 } return ; } int m=tree[rt].mid(); pushdown(rt);//向下更新子树 if(r<=m) update(rt<<1,l,r,v); else if(l>m) update(rt<<1|1,l,r,v); else { update(rt<<1,l,m,v); update(rt<<1|1,m+1,r,v); } } bool vis[M]; void display(int rt) { if(tree[rt].tag!=-1) { if(tree[rt].tag==1) for(int i=tree[rt].l;i<=tree[rt].r;i++) vis[i]=true; return ; } pushdown(rt); display(rt<<1); display(rt<<1|1); } int main() { build(1,0,M); int l,r; char op,a,b; while(scanf("%c %c%d,%d%c",&op,&a,&l,&r,&b)!=-1) { getchar(); l<<=1; if(a=='(') l++; r<<=1; if(b==')') r--; switch(op) { case 'U':update(1,l,r,1);break; case 'I':update(1,0,l-1,0);update(1,r+1,M,0);break; case 'D':update(1,l,r,0);break; case 'C':update(1,0,l-1,0);update(1,r+1,M,0);update(1,l,r,2);break; case 'S':update(1,l,r,2); } } memset(vis,0,sizeof(vis)); display(1); bool flag=true; for(int i=0;i<M;i++) { if(!vis[i]) continue; flag=false; int start=i,end; while(vis[i]&&i<M) i++; printf("%c%d,%d%c ",start&1?'(':'[',start/2,i/2,(i-1)&1?')':']'); } if(flag) puts("empty set"); else printf("\n"); return 0; }
相关文章推荐
- 【转】发布的QT程序无法显示图标和图片的问题
- HTML5移动Web开发(八)——避免文本字体大小重置
- string转换成char
- 排列组合
- 你来擒孟获(最短路)
- C++中的函数模板&&类模板
- 测试用例
- 欢迎使用CSDN-markdown编辑器
- 日常训练赛(国庆)
- SharedPreferences存储数据
- CSS3学习笔记(1)—淡入的文字
- 结对编程项目
- 使用tomcat部署域名网站
- jQuery的选择器中的通配符[id^='code']
- 锐雯上单不给就送(矩阵快速幂)
- 20151006的NOIP模拟赛
- 堆和栈的区别(转过无数次的文章)
- hdu 5296 Annoying problem (LCA)
- Android中铃声总结【安卓源码解析一】
- AE实现空间分析