ZOJ - 1610 Count the Colors(线段树区间更新,单点查询)
1、给了每条线段的颜色,存在颜色覆盖,求表面上能够看到的颜色种类以及每种颜色的段数。
2、线段树区间更新,单点查询。
但是有点细节,比如:
输入:
2
0 1 1
2 3 1
输出:
1 2
这种情况如果不处理,那么由于是检查点的颜色,会检查到0,1,2,3的颜色都为1,认为是一段连续的,就会输出 1 1
需要处理一下,代码中把所有的左端点都+1,避免了这种情况,比较巧妙。
3、
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std; #define L(root) ((root) << 1)
#define R(root) (((root) << 1) + 1) const int MAXN = ; struct st
{
// 区间范围
int left, right;
int flag;//-1没有颜色
} st[MAXN * ];
int color[MAXN];//每种颜色看到的段数
// 建树代码基本不变
void build(int root, int l, int r)
{
st[root].left = l, st[root].right = r, st[root].flag = -;
if (l == r)
{
return;
} int m = l + ((r - l) >> );
build(L(root), l, m);
build(R(root), m + , r);
} int query(int root, int x)//单点查询
{
if (st[root].left == st[root].right)
{
return st[root].flag;
} // 否则需将当前区间的“缓冲”值更新下去并修正各节点区间的总和
if (st[root].flag!=-)
{
st[L(root)].flag = st[root].flag;
st[R(root)].flag = st[root].flag;
st[root].flag = -;
} int m = st[root].left + ((st[root].right - st[root].left) >> );
if (x <= m)
{
return query(L(root), x);
}
else
{
return query(R(root), x);
}
} void update(int root, int l, int r, int v)//区间更新
{
// 如变更区间恰等于节点区间,只修正当前节点区间即可
if (st[root].left == l && st[root].right == r)
{
st[root].flag = v;
return;
} // 否则需向下修正相关节点区间
if (st[root].flag!=-)
{
st[L(root)].flag = st[root].flag;
st[R(root)].flag = st[root].flag;
st[root].flag = -;
} int m = st[root].left + ((st[root].right - st[root].left) >> );
if (r <= m)
{
update(L(root), l, r, v);
}
else if (l > m)
{
update(R(root), l, r, v);
}
else
{
update(L(root), l, m, v);
update(R(root), m + , r, v);
}
} int main()
{
int n,i;
int x1,x2,c;
int lastColor;//记录上一个颜色
int nowColor;//当前颜色
while(~scanf("%d",&n)){
build(,,);
for(i=;i<=n;++i){
scanf("%d%d%d",&x1,&x2,&c);
update(,++x1,x2,c);//++x1表示缩掉前面一点,处理了0 1 1,2 3 1这种情况,而且还符合了左端点从1开始
}
memset(color,,sizeof(color));
lastColor=-;
for(i=;i<=;++i){
nowColor=query(,i);
if(nowColor==lastColor)
continue;
else if(nowColor!=-)
++color[nowColor];
lastColor=nowColor;
}
for(i=;i<=;++i)//颜色标号是0~8000
if(color[i])
printf("%d %d\n",i,color[i]);
printf("\n");
}
return ;
}
c2.这个没有用上面的左端点+1,但是在建树的时候是用的[0,1],[1,2],[2,3],类似这样的建树,比较刁
上面的建树是[0,1],[2,3],类似这样的,还是有点区别的。具体看代码吧。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN=;
struct Node
{
int l,r;
int color;
}segTree[MAXN*];
int color[MAXN];
int temp;
void Build(int i,int l,int r)
{
segTree[i].l=l;
segTree[i].r=r;
segTree[i].color=-;//-1表示没有颜色
if(l+==r)return;
int mid=((l+r)>>);
Build(i<<,l,mid);
Build((i<<)|,mid,r);
}
void insert(int i,int l,int r,int c)
{
if(l==r)return;
if(segTree[i].color==c)return;
if(l<=segTree[i].l&&r>=segTree[i].r)
{
segTree[i].color=c;
return;
}
if(segTree[i].color>=)//存在颜色,往下更新
{
segTree[i<<].color=segTree[i].color;
segTree[(i<<)|].color=segTree[i].color;
segTree[i].color=-;//表示有多种颜色
}
int mid=((segTree[i].l+segTree[i].r)>>);
if(r<=mid) insert(i<<,l,r,c);
else if(l>=mid) insert((i<<)|,l,r,c);
else
{
insert(i<<,l,mid,c);
insert((i<<)|,mid,r,c);
}
segTree[i].color=-;
}
void Count(int i)//统计各颜色的段数
{
if(segTree[i].color==-)
{
temp=-;
return;
}
if(segTree[i].color!=-)
{
if(segTree[i].color!=temp)//temp存的是前一段的颜色
{
color[segTree[i].color]++;
temp=segTree[i].color;
}
return;
}
if(segTree[i].l+!=segTree[i].r)
{
Count(i<<);
Count((i<<)|);
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,a,b,c;
int Max;
while(scanf("%d",&n)!=EOF)
{
Build(,,);
Max=;
while(n--)
{
scanf("%d%d%d",&a,&b,&c);
insert(,a,b,c);
if(c>Max)Max=c;
}
temp=-;
memset(color,,sizeof(color));
Count();
for(int i=;i<=Max;i++)
{
if(color[i])printf("%d %d\n",i,color[i]);
}
printf("\n");
}
return ;
}
ZOJ - 1610 Count the Colors(线段树区间更新,单点查询)的更多相关文章
- ZOJ 1610 Count the Colors(线段树,区间覆盖,单点查询)
Count the Colors Time Limit: 2 Seconds Memory Limit: 65536 KB Painting some colored segments on ...
- zoj 1610 Count the Colors 线段树区间更新/暴力
Count the Colors Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...
- ZOJ 1610 Count the Color(线段树区间更新)
描述Painting some colored segments on a line, some previously painted segments may be covered by some ...
- 【POJ 2777】 Count Color(线段树区间更新与查询)
[POJ 2777] Count Color(线段树区间更新与查询) Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4094 ...
- HDU.1556 Color the ball (线段树 区间更新 单点查询)
HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...
- ZOJ 1610 Count the Colors【题意+线段树区间更新&&单点查询】
任意门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610 Count the Colors Time Limit: 2 ...
- ZOJ 1610 Count the Colors (线段树成段更新)
题意 : 给出 n 个染色操作,问你到最后区间上能看见的各个颜色所拥有的区间块有多少个 分析 : 使用线段树成段更新然后再暴力查询总区间的颜色信息即可,这里需要注意的是给区间染色,而不是给点染色,所以 ...
- HDU 5861 Road 线段树区间更新单点查询
题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Road Time Limit: 12000/6000 MS (Java/Othe ...
- ZOJ 1610.Count the Colors-线段树(区间染色、区间更新、单点查询)-有点小坑(染色片段)
ZOJ Problem Set - 1610 Count the Colors Time Limit: 2 Seconds Memory Limit: 65536 KB Painting s ...
- ZOJ 5638——Prime Query——————【线段树区间更新,区间查询,单点更新】
Prime Query Time Limit: 1 Second Memory Limit: 196608 KB You are given a simple task. Given a s ...
随机推荐
- Python的3种格式化字符串方法
Python中有3种format字符串的方式: 传统C语言式 命名参数 位置参数 1. 传统C语言式 和c语言里面的 sprintf 类似,参数格式也一样 title = "world&qu ...
- 【shell】通过shell编写ping包及arp的监控并发送短信
1 #!/bin/bash 2 NOW="`date +%Y%m%d-%H:%M:%S`" 3 PHONES=15134567893 4 IP=10.100.8.78 5 GATE ...
- 让你的 CDN 费用省 50% 以上!图片瘦身的正确姿势
七牛云新推出的图片瘦身功能是做什么的? 打开七牛云的「数据处理」中的「图片瘦身」功能,在图片受到访问时,能够实时对图片进行瘦身,在保证分辨率和画质不变的情况下,可以将图片最高缩小 80%.当「图片瘦身 ...
- 如何打开Oracle的dmp文件
在工作中经常使用到别人提供过来的dmp文件,由于不知道备份时所用的用户名,这样就不能恢复. 通过打开DMP文件可以查看到备份时使用的用户名. 1.如果dmp文件比较小,用文本编辑器打开就可以了. 2. ...
- 只有代码不会撒谎,如何通过Spring boot源码查看其对于各个框架的默认配置
我发现很多开发对于看源码都有种恐惧心理,其实不必这样,大部分优秀的源码写的都挺直观的,很多时候,你在搜索引擎上搜到的一些东西并不一定是对的,但源码肯定造不了假,毕竟不管你怎么想,它就在那里,该是什么意 ...
- 【BZOJ1031】字符加密Cipher(后缀数组)
题意:将一个长度为2n(复制粘贴后)的字符串的所有长度为n的后缀从小到大排序,并依次输出它们的最后一个字母. n<=100000 思路:裸SA,模板真难背 P党不得不写成C++风格 ..]of ...
- lightoj 1293 - Document Analyzer [ 两指针 + 字符串 ]
传送门 1293 - Document Analyzer PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: ...
- python之-- socket 基础篇
socket 网络模块 注意事项:在python3中,所有数据的传输必须用bytes类型(bytes只支持ascii码)所以在发送数据的时候要么在发送的字符串前面加 'b',要么使用encode('u ...
- Python基础之 一 集合(set)
集合:是一个无序的,不重复的数据组合.主要作用: 去重(把列表变成集合就自动去重) 关系测试 测试俩组数据的交集,差集,并集等关系 关系测试共有7种,如下: 名称 方法名 简写符号 解释交集 s.in ...
- Scrambled Polygon--poj2007(极角排序模板)
http://poj.org/problem?id=2007 #include<stdio.h> #include<math.h> #include<algorithm& ...