poj2777 Count Color 线段树区间更新+位操作
来源:互联网 发布:淘宝金牌卖家怎么申请 编辑:程序博客网 时间:2024/05/21 21:47
传送门:poj2777 Count Color
题目大意
有一个长为L的甲板,能把他平均分为L段,每一段能有不同的颜色,为了简便,颜色可以数字(1,2,…T)代表不同的颜色。初始的时候L段均为颜色1。我们能对这个分为L段的甲板做两种操作:
1. C X Y Z,C代表操作 把区间[X,Y]中所有段变为Z颜色
2. P X Y ,P代表操作,表示查询出[X,Y]中有几种不同的颜色
输入:第一行输入三个整数L(甲板的长度),T(颜色的种类),Q(操作的次数)
下面的Q行输入的是操作,遇到查询操作的时候输出
输出:当执行P操作的时候输出该区间不同的颜色种类
解题思路
线段树的区间更新,用到了延时标记。
还有一个就是如何标记不同的颜色,因为每一种颜色的序号都是不同的,所有可以用位运算的方法,1左移颜色的序号减一位,就代表第几号颜色,初始化的时候颜色均为1。然后通过左后孩子颜色进行与运算得到该元素的颜色数量,颜色数量等于这个颜色中1的位数。
最重要的一点就是,这道题中X是可以大于Y的,这里要注意一下
AC代码
#include<cstdio>#include<algorithm>using namespace std;const int MAXN = 200005;typedef long long LL; //lldLL ans;struct Node{ int left; int right; int color; int addMark; int mid() { return (left+right)>>1; }}tree[MAXN*4];void pushUp(int rt){ tree[rt].color = ( (tree[rt<<1].color) | (tree[rt<<1|1].color)); //通过左右孩子节点的color得到该节点颜色的数量}void buildTree(int left,int right,int rt){ tree[rt].left = left; tree[rt].right= right; tree[rt].addMark = -1; tree[rt].color = 1; if(left == right) { return ; } int mid = tree[rt].mid(); buildTree(left,mid,rt<<1); buildTree(mid+1,right,rt<<1|1); pushUp(rt);}void PushDown(int rt){ if(tree[rt].addMark != -1) { tree[rt<<1].addMark = tree[rt<<1|1].addMark = tree[rt].addMark; tree[rt<<1].color = tree[rt<<1|1].color = tree[rt].color; tree[rt].addMark = -1; }}void queryTree(int left,int right,int rt,int L,int R){ if(left>=L && right<=R) { ans |= tree[rt].color; return ; } PushDown(rt); int mid = tree[rt].mid(); if(L<=mid) queryTree(left,mid,rt<<1,L,R); if(R>mid) queryTree(mid+1,right,rt<<1|1,L,R);}void updateTree(int left,int right,int rt,int L,int R,int color){ if(left>=L && right<=R) { tree[rt].addMark = color; tree[rt].color = color; return ; } PushDown(rt); int mid = tree[rt].mid(); if(L<=mid) updateTree(left,mid,rt<<1,L,R,color); if(R>mid) updateTree(mid+1,right,rt<<1|1,L,R,color); pushUp(rt);}LL tenToLen(LL ans) //计算该数中有多少个1,就代表有几种颜色{ int len = 0; while(ans) { if(ans%2) len++; ans/=2; } return len;}int main(){ int t,n,o; int a,b,c; char ch; scanf("%d%d%d",&n,&t,&o); buildTree(1,n,1); while(o--) { getchar(); scanf("%c",&ch); if(ch == 'C') { scanf("%d%d%d",&a,&b,&c); updateTree(1,n,1,min(a,b),max(a,b),1<<(c-1));//用到了min函数和max保证区间是从大到小 } else if(ch == 'P') { scanf("%d%d",&a,&b); ans = 0; queryTree(1,n,1,min(a,b),max(a,b)); printf("%lld\n",tenToLen(ans)); } } return 0;}
0 0
- poj2777 Count Color 线段树区间更新+位操作
- POJ2777 Count Color 线段树区间更新
- POJ2777 Count Color 线段树区间更新
- 【POJ2777】Count Color-线段树区间更新
- POJ2777 - Count Color (线段树 区间更新)
- Count Color(线段树+位运算 POJ2777)
- POJ2777 Count Color 线段树
- 【poj2777】【线段树】Count Color
- [poj2777 Count Color]线段树
- 线段树 POJ2777 Count Color
- POJ2777 Count Color【线段树】
- poj2777 Count Color(线段树)
- POJ2777 Count Color 线段树
- POJ 2777 Count Color 线段树区间更新位运算
- poj2777 Count Color线段树延迟更新,二进制状态记录
- [luogu1558][POJ2777]Count Color(线段树+二进制操作)
- 线段树区间更新 Count Color
- Count Color (线段树,区间更新)
- 使用Apache HTTP发送POST/GET请求
- Spring学习笔记-1:SpringMVC hello world
- android 轮播图
- 设计模式-观察者模式
- Determining IP information for eth0...failed
- poj2777 Count Color 线段树区间更新+位操作
- Splash.activity闪屏页面的设置
- SDKD 2016 Summer Single Contest #02.A
- Android实战技巧之十二:Android Studio导入第三方类库、jar包和so库
- [NOIP1999]拦截导弹
- 声学
- 1326. Window (Standard IO)
- 【Android】SQLite 数据库基本操作
- ACM中的博弈论入门(二) POJ 2960 SG 函数的应用