poj 2777 线段树难题
2015-08-21 21:41
344 查看
题意:
给一个固定长度为L的画板,有两个操作:
C A B C:区间AB内涂上颜色C。
思路:线段树的好题,线段树 + lazy思想的经典应用。而且和位运算结合到了一起。因为颜色数量很少,而且父结点的颜色正好是两个子结点颜色的按位或,因此可以用位运算。最后1的个数就是不同颜色的个数。P A B:查询区间AB内颜色种类数。
参考博客:点击打开链接
给一个固定长度为L的画板,有两个操作:
C A B C:区间AB内涂上颜色C。
思路:线段树的好题,线段树 + lazy思想的经典应用。而且和位运算结合到了一起。因为颜色数量很少,而且父结点的颜色正好是两个子结点颜色的按位或,因此可以用位运算。最后1的个数就是不同颜色的个数。P A B:查询区间AB内颜色种类数。
参考博客:点击打开链接
#include<iostream> #include<stdio.h> using namespace std; int l,t,o; const int L=100005,T=35,O=100005; int colour; void swap(int &a,int &b) { int t=a; a=b; b=t; } struct Node { int l,r; int color; bool cover; }node[6*L]; void build(int index,int l,int r) { node[index].l=l; node[index].r=r; node[index].color|=1; if(l==r) { return; } int mid=(l+r)/2; build(index<<1,l,mid); build((index<<1)+1,mid+1,r); } void insert(int index,int begin,int end,int value) { if(node[index].l==begin&&node[index].r==end) { node[index].color=(1<<(value-1)); node[index].cover=true; return; } if(node[index].cover) { node[index].cover=false; node[index<<1].cover=true; node[(index<<1)+1].cover=true; node[index<<1].color=node[index].color; node[(index<<1)+1].color=node[index].color; } int mid=(node[index].l+node[index].r)/2; if(end<=mid) { insert(index<<1,begin,end,value); } else if(begin>mid) { insert((index<<1)+1,begin,end,value); } else { insert(index<<1,begin,mid,value); insert((index<<1)+1,mid+1,end,value); } node[index].color=node[index*2].color | node[index*2+1].color; } void query(int index,int begin,int end) { if(node[index].cover||(begin==node[index].l&&end==node[index].r)) { colour|=node[index].color; return; } int mid=(node[index].l+node[index].r)/2; if(end<=mid) { query(index<<1,begin,end); } else if(begin>mid) { query((index<<1)+1,begin,end); } else { query((index<<1),begin,mid); query((index<<1)+1,mid+1,end); } } int main() { scanf("%d%d%d",&l,&t,&o); char a[2]; int from,to,color; build(1,1,l); for(int i=1;i<=o;i++) { scanf("%s",&a); scanf("%d%d",&from,&to); if(from>to) swap(from,to); if(a[0]=='C') { scanf("%d",&color); insert(1,from,to,color); } else { int ans=0; colour=0; query(1,from,to); for(int i=0;i<t;i++) { if(colour&(1<<i)) ans++; } printf("%d\n",ans); } } return 0; }
相关文章推荐
- 施一公在《科学》发表突破性成果 专家称有望拿诺奖
- poj 2513 Colored Sticks(欧拉路径+并检查集合+特里)
- Mysql 建表 数据类型选择
- NYOJ-458:小光棍数
- java.lang.UnsatisfiedLinkError: Couldn't load libjniFramework from loader
- 寻找数组中的最大值和最小值
- 五大常用算法之四:回溯法
- [C++11 并发编程] 08 - Mutex std::unique_lock
- HDU 1394 Minimum Inversion Number
- 黑马程序员----java基础之异常和File文件类
- 【待整理】IOS开发之下载
- 求点云的边界的方法小结
- 黑马程序员--Java基础学习(面向对象)第八天
- CodeForces-551A GukiZ and Contest
- 记录glibc编译失败经历
- JAVA反射机制
- Gift Hunting(分组背包)
- HDOJ--1248--寒冰王座
- 组合——Program B
- Android问题:设置了requestWindowfeature(window.feature_no_title)后,为什么还要getwindow.setFlags?