题目链接:贪婪大陆 - 洛谷

分析:先说一个容易引起误会的地方,就是同一个地方可以存在多种颜色,这也是本道题目最大的坑点,我一开始就以为后来染色会把之前染过色的地方覆盖掉,那这样就不太好处理了,而这道题目告诉我们对一段区间进行染色,颜色只能是这段区间不存在的,所以这也就给了我们一点启发意义:我们并不需要真正的对染的颜色关注太多,因为我们不可能去遍历哪一种颜色在该区间未出现过,下面给出正解:

我们只需要建立两棵线段树,一棵线段树中存储染色区间的起点,另一棵线段树中存储染色区间的终点,然后我们每次对一块区间[l,r]进行染色只需要把区间左端点的位置在第一棵线段树上加1,把区间右端点的位置在第二棵线段树上加1,这样我们就保证了区间[l,r]上一定有该号颜色(因为我们选取的颜色之前在区间[l,r]上是不存在的),那我们怎么知道一块区间[l,r]上有多少种颜色呢?我们可以这样考虑,可能出现在区间[l,r]上的染色区间肯定满足左边界在r前面,所以我们可以先找一下之前染色区间左边界在r之前的有多少种颜色,这些染色区间的右边界有两种情况,一种是在[1,l-1],一种是在[l,+无穷大],第一种情况的染色区间不会与[l,r]有交集,而后一种情况的染色区间一定会与[l,r]有交集,所以我们只要用染色区间左边界在r及之前的染色区间数量减去染色区间右边界在l之前的染色区间数量即可得到目标区间的颜色种类。

可以用线段树实现,也可以用树状数组实现,下面分别给出两种代码,后面还会对本题做出相应变形

线段树版本代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
const int N=1e6+10;
int l[2][N],r[2][N],sum[2][N];
void pushup(int t,int id)
{sum[t][id]=sum[t][id<<1]+sum[t][id<<1|1];
}
void build(int t,int id,int L,int R)
{l[t][id]=L;r[t][id]=R;sum[t][id]=0;if(L==R) return ;int mid=L+R>>1;build(t,id<<1,L,mid);build(t,id<<1|1,mid+1,R);
}
void update_point(int t,int id,int x,int val)
{if(l[t][id]==r[t][id]){sum[t][id]+=val;return ;}int mid=l[t][id]+r[t][id]>>1;if(x<=mid) update_point(t,id<<1,x,val);else update_point(t,id<<1|1,x,val);pushup(t,id);
}
int query_interval(int t,int id,int L,int R)
{if(l[t][id]>=L&&r[t][id]<=R) return sum[t][id];int mid=l[t][id]+r[t][id]>>1;int ans=0;if(L<=mid) ans+=query_interval(t,id<<1,L,R);if(mid+1<=R) ans+=query_interval(t,id<<1|1,L,R);return ans;
}
int main()
{int n,m;cin>>n>>m;build(0,1,1,n);//储存起点 build(1,1,1,n);//储存终点 for(int i=1;i<=m;i++){int op,a,b;scanf("%d%d%d",&op,&a,&b);if(op==1){update_point(0,1,a,1);update_point(1,1,b,1);}else{int ans=query_interval(0,1,1,b)-query_interval(1,1,1,a-1);printf("%d\n",ans);}}return 0;
}

树状数组版本代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
const int N=1e6+10;
int c[2][N],n,m;
int lowbit(int x)
{return x&(-x);
}
int sum(int k,int x)
{int ans=0;for(;x;x-=lowbit(x))ans+=c[k][x];return ans;
}
void add(int k,int x,int val)
{for(;x<=n;x+=lowbit(x))c[k][x]+=val;
}
int main()
{cin>>n>>m;for(int i=1;i<=m;i++){int op,a,b;scanf("%d%d%d",&op,&a,&b);if(op==1){add(0,a,1);add(1,b,1);}else{int ans=sum(0,b)-sum(1,a-1);printf("%d\n",ans);}}return 0;
}

倘若这道题目是覆盖颜色,那就需要用另一种方法来解决了,就是说每次输入一段区间告诉你将要染色的颜色,然后问你某段区间内存在的颜色种数,下面给出颜色种数较少情况下的思路分析

我们可以把一个区间存在的颜色用一个数的二进制来表示,其实这个很简单,比如某一段区间的颜色是9,其对应的二进制为1001,这就意味着这段区间上存在2种颜色,也就是说某段区间的颜色种数就是这段区间颜色值的二进制表示中1的个数,至于pushup操作,就是当前区间的两个子区间的或值,然后剩下的就是一个线段树模板了

具体题目见:Count Color(线段树)_AC__dream的博客-CSDN博客

P2184 贪婪大陆(线段树或树状数组+思维)相关推荐

  1. 洛谷 P2184 贪婪大陆 解题报告

    P2184 贪婪大陆 题目背景 面对蚂蚁们的疯狂进攻,小\(FF\)的\(Tower\) \(defence\)宣告失败--人类被蚂蚁们逼到了\(Greed\) \(Island\)上的一个海湾.现在 ...

  2. 【树状数组 思维题】luoguP3616 富金森林公园

    树状数组.差分.前缀和.离散化 题目描述 博艾的富金森林公园里有一个长长的富金山脉,山脉是由一块块巨石并列构成的,编号从1到N.每一个巨石有一个海拔高度.而这个山脉又在一个盆地中,盆地里可能会积水,积 ...

  3. 【洛谷】P2184 贪婪大陆

    题目地址: https://www.luogu.com.cn/problem/P2184 题目背景: 面对蚂蚁们的疯狂进攻,小FF的Tower defence宣告失败--人类被蚂蚁们逼到了Greed ...

  4. P2184 贪婪大陆

    题目背景 面对蚂蚁们的疯狂进攻,小FF的Tower defence宣告失败--人类被蚂蚁们逼到了Greed Island上的一个海湾.现在,小FF的后方是一望无际的大海, 前方是变异了的超级蚂蚁. 小 ...

  5. hdoj 4417 Super Mario 【树状数组 + 思维】

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  6. HDU - 5775 - Bubble Sort( 树状数组 + 思维 )

    题目链接:点击进入 题目 题意 问在给出的冒泡排序过程中,一个数到达的最右边位置与最左边位置距离差. 思路 对于一个数,位置 i ,假设右边比它小的数有 r 个,左边比它大的数有 l 个,最右边到达的 ...

  7. lugou P2184 贪婪大陆(线段树)

    题目描述 小 FF 最后一道防线是一条长度为 nn 的战壕,小 FF 拥有无数多种地雷,而 SCV 每次可以在 [L, R]区间埋放同一种不同于之前已经埋放的地雷.由于情况已经十万火急,小 FF 在某 ...

  8. 牛客练习赛34 - C little w and Segment Coverage(思维、树状数组)

    title: 牛客练习赛34 - C little w and Segment Coverage(思维.树状数组) date: 2018-12-15 16:36:55 tags: [树状数组,思维] ...

  9. 树套树 ----- P1975 [国家集训队]排队(树状数组套权值线段树求动态逆序对)

    解题思路: 首先我们知道交换两个数a[l]和a[r]a[l]和a[r]a[l]和a[r]影响到的区间是[l+1,r−1][l+1,r-1][l+1,r−1] 对于a[l]a[l]a[l],我们要减去[ ...

  10. 树套树 ---- 树状数组套权值线段树模板题 P2617 Dynamic Rankings 动态第K大

    题目链接 题目大意: 给你一个数组aaa,aaa有两个操作 询问aaa中[l,r][l,r][l,r]区间里面第kkk小的数是哪个? 修改axa_xax​为yyy 解题思路: 首先我们知道权值线段树是 ...

最新文章

  1. 逆误差函数:torch.erfinv
  2. 【Web安全】Payload的探索与Kali渗透测试框架-msf
  3. STP生成树协议与MSTP的基本原理与简单配置
  4. Font Awesome 中文网
  5. AWS CEO Andy Jassy 专访:我们一直思考的是未来 2-5 年的事 | 人物志
  6. docker学习(三) 安装docker的web可视化管理工具
  7. Codeforces 1114C(数论+唯一分解)
  8. Linux动态库soname的使用(转载)
  9. 在计算机上设置桌面,如何在计算机上设置动态桌面墙纸
  10. 表达式类型错误oracle,PL/SQL编译错误 - PLS-00382:表达式类型错误
  11. 猿人学web端爬虫攻防大赛赛题解析_第六题:js 混淆 - 回溯
  12. ip 查找计算机,win10系统通过ip地址查找计算机名的详细技巧
  13. 医学图像分析领域算法汇总
  14. 阅读分享——李开复老师《开工愉快:如何保持每天精力充沛》
  15. 小记!华为 8.0系统切换APP内语言(中英文)无效(其他版本手机均有效)。
  16. 【小说】MR设备普及后的生活
  17. SpringCloud的五大核心组件李俊老师
  18. sql:查询选修了全部课程的学生姓名
  19. python绘图:散点图
  20. 为什么聪明人未能拯救世界?|《流浪地球》冷思考

热门文章

  1. 【不积跬步_无以至千里】 数学知识(不定时整理)
  2. 计算机fn的作用,必看干货!笔记本电脑fn键的作用
  3. 黑客攻击-木马程序(3)
  4. Python爬虫-QQ音乐下载(详解)
  5. ui和ux的区别_UX和UI设计之间有什么区别?
  6. WINDOWS 7 X86专业版SP1后续补丁包20150901(微软官方下载地址列表)
  7. 许巍的故乡到底想表达什么?是写给谁的?
  8. 在Windows 10下提取/读取 Linux img 镜像文件
  9. 电影《海贼王:红发歌姬》观后感
  10. expected primary-expression before ‘int‘