title: zoj-1610线段树刷题

date: 2018-10-16 16:49:47

tags:

  • acm
  • 刷题

    categories:
  • ACM-线段树

概述

这道题是一道简单的线段树区间染色问题,,,

但是,,,,刚学lazy更新没多久的我看到这样的题心里还是发怵,,,

本来是一道简单的题一开始就是不知道怎么用线段树维护染色的区间,,,还有一个老毛病,,,还是不知道怎么把题目里的信息抽象出来,,,

明确线段树所要维护的信息以及如何对这些信息如何更新和查询,,,

思路分析

  • 这道题和前几天做的那道贴海报的题很像,,,都是在一个很大的区间里进行连续的区间覆盖操作,,,

  • 然后问你最后露出来的颜色、海报有几种,,,只不过这道题是要列出每种颜色出现了几个区间,,,

  • 首先,,,这道题染色是区间之间的染色,,,就是说"1 2 1"是指在1 , 2这个长度只有1的区间里染色成颜色1,,,而那道海报的题是指1 , 2这两个块贴上海报,,,,这就意味着我们用线段树来维护染色操作时要将所给的左端点加一,,

  • 全部染色完了(更新)之后,,,就是对整个区域查询,,,然后把有颜色覆盖的区域都保存到另一个数组里,,,也就是最后染色后的区域,,,然后遍历这个区域,,,数出对应的颜色的个数就行了,,,

  • 更新时用到了lazy操作

参考

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring> using namespace std; #define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define aaa cout<<"2333"<<endl;
const int maxn = 8005; int col[maxn << 2];
int vis[maxn << 2];
int ans[maxn << 2]; void pushdown(int rt)
{
if(~col[rt])
{
col[rt << 1] = col[rt << 1 | 1] = col[rt];
col[rt] = -1;//父节点有多种染色标记为-1
}
}
void update(int rt , int l , int r , int L , int R , int val)
{
if(L <= l && r <= R)
{
//当该区间在所要染色的区间里时染色
col[rt] = val;
return;
}
if(col[rt] == val) return;
int mid = (l + r) >> 1;
if(~col[rt]) //染过色又要染其他颜色时下推
pushdown(rt);
if(L <= mid) update(lson , L , R , val);
if(R > mid) update(rson , L , R , val);
return;
}
void query(int rt , int l , int r)
{
if(col[rt] >= 0)
{
//把存在的颜色保存到vis数组里
for(int i = l; i <= r; ++i)
vis[i] = col[rt];
return;
}
if(col[rt] == -1 && l != r)
{
//已经保存的区间就不再查询了
int mid = (l + r) >> 1;
query(lson);
query(rson);
}
return;
}
int main()
{
int n;
while(scanf("%d" , &n) != EOF)
{
//初始化操作,,,无需再建树
memset(col , -1 , sizeof(col));
memset(vis , -1 , sizeof(vis));
memset(ans , 0 , sizeof(ans));
int a , b , c;
for(int i = 1; i <= n; ++i)
{
scanf("%d%d%d" , &a , &b , &c);
update(1 , 1 , 8000 , a + 1 , b , c);//左端点++
} query(1 , 1 , 8000); //数出每个颜色的个数
int i = 1;
while(i < maxn)
{
int color = vis[i];
int j = i + 1;
if(color == -1)
{
++i;
continue;
}
while(~vis[j] && vis[j] == color && j < maxn) ++j;
++ans[color];
i = j;
} for(int i = 0; i < maxn; ++i)
{
if(ans[i]) //颜色存在输出
printf("%d %d\n" , i , ans[i]);
}
printf("\n");
}
}

总结

  • 还是不能找不出维护的信息以及如何查询
  • 染色问题是线段树的区间覆盖问题,,,节点一般保存颜色信息

zoj-1610线段树刷题的更多相关文章

  1. hdu-1540线段树刷题

    title: hdu-1540线段树刷题 date: 2018-10-18 19:55:21 tags: acm 刷题 categories: ACM-线段树 概述 哇,,,这道线段树的题可以说是到目 ...

  2. hdu-5023线段树刷题

    title: hdu-5023线段树刷题 date: 2018-10-18 13:32:13 tags: acm 刷题 categories: ACM-线段树 概述 这道题和上次做的那道染色问题一样, ...

  3. poj-2777线段树刷题

    title: poj-2777线段树刷题 date: 2018-10-16 20:01:07 tags: acm 刷题 categories: ACM-线段树 概述 这道题是一道线段树的染色问题,,, ...

  4. F - Count the Colors ZOJ - 1610 线段树染色(染区间映射)

    题意:给一段0-8000的线段染色 问最后 颜色x 有几段 题解:标准线段树  但是没有push_up  最后查询是单点按顺序查询每一个点 考虑过使用区间来维护不同的线段有多少种各色的线段  思路是 ...

  5. POJ 3468 线段树裸题

    这些天一直在看线段树,因为临近期末,所以看得断断续续,弄得有些知识点没能理解得很透切,但我也知道不能钻牛角尖,所以配合着刷题来加深理解. 然后,这是线段树裸题,而且是最简单的区间增加与查询,我参考了A ...

  6. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

  7. Codeforces Round #393 (Div. 2) (8VC Venture Cup 2017 - Final Round Div. 2 Edition) E - Nikita and stack 线段树好题

    http://codeforces.com/contest/760/problem/E 题目大意:现在对栈有m个操作,但是顺序是乱的,现在每输入一个操作要求你输出当前的栈顶, 注意,已有操作要按它们的 ...

  8. hdu 1754 I Hate It 线段树基础题

    Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求, ...

  9. 【LOJ6062】「2017 山东一轮集训 Day2」Pair(线段树套路题)

    点此看题面 大致题意: 给出一个长度为\(n\)的数列\(a\)和一个长度为\(m\)的数列\(b\),求\(a\)有多少个长度为\(m\)的子串与\(b\)匹配.数列匹配指存在一种方案使两个数列中的 ...

随机推荐

  1. IE6下面的css调试工具

    在开发过程中,代码部分实现之后,就要着手于前台展示部分的界面,公司的美工又是新手,无奈,只有自己慢慢调了,但IE6之前的版本都没有好的调试工具,后来在网上搜索了一个 IE Developer Tool ...

  2. Donald Ervin Knuth:最年轻的图灵奖高德纳

    高德纳(Donald Ervin Knuth,1938年),美国著名计算机科学家,斯坦福大学电脑系荣誉教授.高德纳教授被誉为现代计算机科学的鼻祖,在计算机科学及数学领域发表了多部 具广泛影响的论文和著 ...

  3. 【CodeForces】961 G. Partitions 斯特林数

    [题目]G. Partitions [题意]n个数$w_i$,每个非空子集S的价值是$W(S)=|S|\sum_{i\in S}w_i$,一种划分方案的价值是所有非空子集的价值和,求所有划分成k个非空 ...

  4. NYOJ 119 士兵杀敌(三) (线段树)

    题目链接 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算 ...

  5. C++ Primer 5th 第18章 用于大型程序的工具

    C++大规模程序设计至少存在三个特殊要求: 错误处理 库的引入 复杂建模 以上三种对应C++语言的三种特性:异常处理.命名空间.多重继承. 异常处理 异常处理机制是一种允许偷懒的工具,在出现非正确的情 ...

  6. JS获取元素内容属性以及修改

    1.通过document对象

  7. 邮件伪造测试-Swaks

    1. 前言 在kali中自带一个邮件伪造工具Swaks,工具项目主页为 http://jetmore.org/john/code/swaks 2.基本用法: swaks --to --from --e ...

  8. Redhat制作本地yum源

    1.将iso文件上传到服务器上,然后执行: mount -o loop rhel-server-6.3-dvd.iso /media/cdrom 2.设置yum源,在/etc/yum.repos.d目 ...

  9. idea中使用tomcat 方式启动spring boot项目

    Spring boot 的main 入口启动方式相信都会用,直接运行main直接就启动了,但是往往这种方式并不是最佳的启动方式,比如运维的层面更希望调整tomcat的调优参数,而只使用嵌入启动方式很难 ...

  10. poj3636

    题意:每个物品有两个属性:长和宽(长宽不可互换).如果一个物品的长和宽均大于另一个物品,则这个物品可以罩住另一个物品,用这种罩住物品的方法将物品分组,一组之内的物品可以一个罩住一个的全部罩起来.问最少 ...