poj2777线段树+涂色问题
2016-08-18 09:20
323 查看
这个吧,很经典,线段树真的很难debug,很长的。这道题主要是用到了二进制位运算的方法。我现在感觉计算机才发明了这么几年,就这么厉害。真的感觉自己好菜好菜。debug都用了这么久。诶。。。。。
#include<cstdio> #include<cstring> using namespace std; const int MaxN = 100010; struct tree{ int l , r , col ; bool cover;//1表示区间都是一种颜色 }tree[MaxN << 2]; int sum;//位运算有几个1就是几种颜色 void PushUp(int rt){ tree[rt].col = tree[rt << 1].col | tree[rt << 1 | 1].col; } void buildT(int l , int r , int rt) { tree[rt].l = l; tree[rt].r = r; tree[rt].col = 1;//一开始都是一种颜色 tree[rt].cover = 1;//每个叶子节点的颜色都相同 if(tree[rt].l == tree[rt].r) return; int m = (l + r ) >> 1; buildT(l , m , rt << 1); buildT(m + 1 , r , rt << 1 | 1); } void PushDown(int rt)//更新叶子节点 { tree[rt << 1].col = tree[rt].col; tree[rt << 1].cover = 1; tree[rt << 1 | 1].col = tree[rt].col; tree[rt << 1 | 1].cover = 1; tree[rt].cover = 0; } void update(int val , int l , int r, int rt)//更新操作 { if(l <= tree[rt].l && r >= tree[rt].r){ tree[rt].col = val; tree[rt].cover = 1; return ; } if(tree[rt].col == val) return ; if(tree[rt].cover) PushDown(rt); int m = (tree[rt].l + tree[rt].r) >> 1; if(r <= m) update(val , l , r , rt << 1); else if(l > m) update(val , l , r ,rt << 1 | 1); else{ update(val , l , m , rt << 1 ); update(val ,m + 1 , r , rt << 1 | 1); } PushUp(rt);//更新爸爸节点 } void query(int l , int r , int rt) { if(l <= tree[rt].l && r >= tree[rt].r){ sum |= tree[rt].col; return; } if(tree[rt].cover){ sum |= tree[rt].col; return; } int mid = (tree[rt].l + tree[rt].r) >> 1; if(r <= mid) query(l , r , rt << 1); else if(l > mid) query(l , r , rt << 1 | 1); else{ query(l , mid , rt << 1); query(mid + 1, r ,rt << 1 | 1); } } int solve()//计算有几种颜色 { int ans = 0; while(sum){ if(sum & 1) ans++; sum >>= 1; } return ans; } void swap(int &a,int &b) { int tmp = a; a = b; b = tmp; } int main(){ //freopen("input.txt","r",stdin); int n,t,m; while(~scanf("%d%d%d",&n,&t,&m)){ buildT(1,n,1); char op[3]; int a,b,c; while(m--){ scanf("%s",op); if(op[0]=='C'){ scanf("%d%d%d",&a,&b,&c); if(a>b) swap(a,b); update(1<<(c-1),a,b,1); // int型的右起第c位变为1,即2的c-1次方。 }else{ scanf("%d%d",&a,&b); if(a>b) swap(a,b); sum=0; query(a,b,1); printf("%d\n",solve()); } } } return 0; }
相关文章推荐
- zzuli 1919 (晴天分割序列)
- UIBezierPath精讲
- JS中如何使用类似JAVA中的StringBuffer
- Android仿微信朋友圈发动态功能(相册图片多选)
- java中HashMap详解
- easyui tree基本操作
- Java异常处理之最佳实践
- Java之基本数据的类型转换
- iOS - OC NSSet 集合
- leetCode_Permutation Sequence
- 数据结构实验之排序四:寻找大富翁
- 关于noip错误总结
- linux下安装telnet
- 数据类型转换
- Java之多线程中的Future模式
- iOS开发基础知识--碎片3
- NOIP 2014 Day2 T2 寻找道路
- Spring+Hibernate在Application.context.xml文件中配置数据源信息
- 业务渗透思路总结
- Skype For Business 2015实战系列7:准备活动目录