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 ...
随机推荐
- iTextSharp.text的一个使用,主要用来创建PDF
using iTextSharp.text; //创建一个字体来使用和编码格式 BaseFont baseFont = BaseFont.CreateFont("C:\\Windows\\F ...
- ASP.net 学习路线(详细)
.net学习路线 入门篇1. 学习面向对象(OOP)的编程思想 许多高级语言都是面向对象的编程,.NET也不例外.如果您第一次接触面向对象的编程,就必须理解类.对象.字段.属性.方法和 ...
- mysql版sql助记
新建用户 CREATE USER 'username'@'host' IDENTIFIED BY 'password'; [host 中 使用 % 为通配符, 匹配任意远程主机] 赋权 GRANT p ...
- ZOJ 3203 Light Bulb - 求导求最大值
如果L全在地面上: 输出 h * D / H 如果L全在墙上: 输出 h 否则: (D - X ) / X = Y / (H - h) L = D - X + h - Y 然后对L求导即可 #incl ...
- access数据库
//访问动态创建access数据库 string conn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.M ...
- WinForm - 格式化DataGridView单元格数据
效果: 代码: /// <summary> /// 格式化数据 /// </summary> private void dataGridView1_CellFormatting ...
- python package的概念
主目录下面文件夹pack,可以按照 import pack.mo as mo 来调用模块,意为把pack文件夹当作一个包
- 文件打包bundle
做项目时,经常会有一些资源拷来拷去会很麻烦,打包这些文件到项目里会方便很多! 首先把文件放到一个文件夹里 然后重命名文件夹为iToast.bundle 拖到项目里 如何访 ...
- Ubuntu一些配置和技巧
安装google-chrome wget https://dl.google.com/linux/direct/google-chrome-stable_current_i386.deb sudo d ...
- 科尔尼咨询公司 - MBA智库百科
科尔尼咨询公司 - MBA智库百科 科尔尼公司简介 科尔尼管理咨询公司(A.T. Kearney)于1926年在芝加哥成立,经过80多年的发展,科尔尼咨询已发展为一家全球领先的高增值管理咨询公司,科尔 ...