poj 2777 Count Color(线段树区区+染色问题)
题目链接: poj 2777 Count Color
题目大意: 给出一块长度为n的板,区间范围[1,n],和m种染料
k次操作,C a b c 把区间[a,b]涂为c色,P a b 查询区间[a,b]有多少种不同颜色
解题思路: 很明显的线段树的区间插入和区间查询,但是如何统计有多少不同的颜色呢?
如果每个结点数组来存储颜色的种类,空间复杂度很高,而且查询很慢
颜色最多只有30种,可以用位运算中的“按位或|”
颜色也用二进制来处理,和存储:
第一种颜色的二进制表示1
第二种颜色的二进制表示10
第三种颜色的二进制表示100
第四种颜色的二进制表示1000
如同一个区间出现第一种和第三种颜色,按位或运算之后得到 101
统计结果有多少个1,就说明区间有多少不同的颜色
线段树每个结点存储区间颜色的种类,结点=左子树|右子树
更多关于线段树的解题报告可以看我博客 myzee.cn
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 110000
#define MID(a,b) (a+b)>>1
#define L(a) a<<1
#define R(a) (a<<1|1)
typedef struct{
int left,right;
int add,num;
}Node;
Node Tree[MAX<<2];
int Color[32]={0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824};
//二进制表示第几种颜色,如8表示第四种颜色:1000
int Lowbit(int x) //剔除x二进制中最后面一个1
{
return x&(-x);
} void Build(int t,int l,int r) //以1为根结点,建立[l,r]的线段树
{
Tree[t].left=l,Tree[t].right=r,Tree[t].add=0; //***
if(l==r)
{
Tree[t].num=1;
return ;
}
int mid=MID(Tree[t].left,Tree[t].right);
Build(L(t),l,mid);
Build(R(t),mid+1,r);
Tree[t].num=(Tree[L(t)].num|Tree[R(t)].num);
} void Insert(int t,int l,int r,int m) //向区间[l,r]涂颜色
{
if(Tree[t].left==l&&Tree[t].right==r)
{
Tree[t].add=m;
Tree[t].num=m;
return ;
}
if(Tree[t].add!=0) //lazy标记
{
Tree[L(t)].num=Tree[t].add;
Tree[R(t)].num=Tree[t].add;
Tree[L(t)].add=Tree[t].add;
Tree[R(t)].add=Tree[t].add;
Tree[t].add=0;
}
int mid=MID(Tree[t].left,Tree[t].right);
if(l>mid)
{
Insert(R(t),l,r,m);
}
else if(r<=mid)
{
Insert(L(t),l,r,m);
}
else
{
Insert(L(t),l,mid,m);
Insert(R(t),mid+1,r,m);
}
Tree[t].num=(Tree[L(t)].num|Tree[R(t)].num); //***
} int Query(int t,int l,int r)
{
if(Tree[t].left==l&&Tree[t].right==r)
{
return Tree[t].num;
}
if(Tree[t].add!=0) //区间插入的lazy思想
{
Tree[L(t)].num=Tree[t].add;
Tree[R(t)].num=Tree[t].add;
Tree[L(t)].add=Tree[t].add;
Tree[R(t)].add=Tree[t].add;
Tree[t].add=0;
}
int mid=MID(Tree[t].left,Tree[t].right);
if(l>mid)
{
return Query(R(t),l,r);
}
else if(r<=mid)
{
return Query(L(t),l,r);
}
else
{
return Query(L(t),l,mid)|Query(R(t),mid+1,r); //***是|,不是+!!!
}
Tree[t].num=(Tree[L(t)].num|Tree[R(t)].num);
} int main()
{
char ch;
int n,col,q,i,k,a,b,c;
int m;
while(scanf("%d%d%d",&n,&col,&q)!=EOF)
{
memset(Tree,0,sizeof(Tree)); //初始化
Build(1,1,n); //建树
for(i=0;i<q;i++)
{
getchar();
scanf("%c",&ch);
if(ch=='P')
{
scanf("%d%d",&a,&b);
k=0;
if(a>b)
m=Query(1,b,a);
else
m=Query(1,a,b);
while(m>0) //计算查询后的结果的二进制表示右多少个1
{
k++;
m-=Lowbit(m);
}
printf("%d\n",k);
}
else
{
scanf("%d%d%d",&a,&b,&c);
if(a>b)
Insert(1,b,a,Color[c]);
else
Insert(1,a,b,Color[c]);
}
}
}
return 0;
}
注:原创文章,转载请注明出处
poj 2777 Count Color(线段树区区+染色问题)的更多相关文章
- poj 2777 Count Color(线段树)
题目地址:http://poj.org/problem?id=2777 Count Color Time Limit: 1000MS Memory Limit: 65536K Total Subm ...
- poj 2777 Count Color(线段树、状态压缩、位运算)
Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 38921 Accepted: 11696 Des ...
- poj 2777 Count Color - 线段树 - 位运算优化
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 42472 Accepted: 12850 Description Cho ...
- POJ 2777 Count Color(线段树之成段更新)
Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 33311 Accepted: 10058 Descrip ...
- POJ 2777 Count Color (线段树成段更新+二进制思维)
题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...
- POJ P2777 Count Color——线段树状态压缩
Description Chosen Problem Solving and Program design as an optional course, you are required to sol ...
- POJ 2777.Count Color-线段树(区间染色+区间查询颜色数量二进制状态压缩)-若干年之前的一道题目。。。
Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 53312 Accepted: 16050 Des ...
- POJ 2777 Count Color(段树)
职务地址:id=2777">POJ 2777 我去.. 延迟标记写错了.标记到了叶子节点上.. . . 这根本就没延迟嘛.. .怪不得一直TLE... 这题就是利用二进制来标记颜色的种 ...
- poj 2777 Count Color
题目连接 http://poj.org/problem?id=2777 Count Color Description Chosen Problem Solving and Program desig ...
随机推荐
- c++,模板函数的定义和使用【初探】
// demo.cpp : // 模版函数的定义和使用: // 1.模板支持返回参数类型为模板参数. // template <typename RET_T , typename IN1_T , ...
- emacs打开乱码解决办法
前言:有时候我们使用emacs打开文件的时候,因为emacs默认编码跟文档编码不同而出现了乱码如图: 对于新手的我们应该通过以下两种途径来解决: 方法一: 只需C-x <RET> r ( ...
- java:转换时间格式为String
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); Date curDate = new ...
- Week10(11月11日):一个激动的日子
Part I:提问 =========================== 请回答视图和控制器传递数据的方法. Part II:案例学习 =========================== Mu ...
- Impossible WPF Part 2: Binding Expressions
原文 http://www.11011.net/wpf-binding-expressions Back in April I posted an idea for building an expre ...
- 人人都用 Retina 屏幕的 MacBook Pro 笔记本电脑
自从今年年初 Apple 官网产品降价我立即买了 13 寸的 Retina 屏 MacBook Pro(rMBP)之后, 这款苹果的笔记本电脑就成了我在公司和家里的唯一电脑(就是这一款). 使用苹果的 ...
- THUSC2015
这些题目在BZOJ上面有,可惜是权限题.话说BZOJ上面的题目真的挺好的,要不是我穷,早就去弄个号了! 言归正传,今年的题目难度可以由一个名人名言看出: 题目太水.--某某神犇 可是我掂量了一下,发现 ...
- mysql如何开启远程连接
链接地址:http://jingyan.baidu.com/article/046a7b3ed85f3ef9c27fa9dc.html 大家在公司工作中,经常会遇到mysql数据库存储于某个人的电脑上 ...
- 1688: [Usaco2005 Open]Disease Manangement 疾病管理( 枚举 )
我一开始写了个状压dp..然后没有滚动就MLE了... 其实这道题直接暴力就行了... 2^15枚举每个状态, 然后检查每头牛是否能被选中, 这样是O( 2^15*1000 ), 也是和dp一样的时间 ...
- [ASP.NET]以iTextSharp手绘表格并产生PDF下载
原文 [ASP.NET]以iTextSharp手繪表格並產生PDF下載 大家使用iTextSharp的機緣都不太一樣, 由於單位Crystal Report的License數量有限主管要我去找一個免費 ...