【BZOJ1067】[SCOI2007] 降雨量(RMQ+分类讨论)
大致题意:请你判断“\(x\)年是自\(y\)年以来降雨量最多的”这句话的真假。
离散化/\(lower\_bound\)
首先,考虑到年份的范围非常大,便可以离散化。
而我比较懒,反正题目中说了年份是递增的,因此我直接用了\(C++\)自带的\(lower\_bound\)。
\(RMQ\)
这题还需要使用的一个算法便是\(RMQ\)。
这应该是一个比较基础的算法吧,这里就不多加介绍了。
至于哪里需要使用,后面你就知道了。
分类讨论
考虑如果是\(false\),则无非有\(3\)种情况:
- 左边界的降雨量已知且小于等于左右边界间的最大降雨量。
- 右边界的降雨量已知且小于等于左右边界间的最大降雨量。
- 左、右边界降雨量皆已知且左边界降雨量小于右边界降雨量。
这里要求区间最大降雨量,就需要使用前面提到过的\(RMQ\)了。
注意\(RMQ\)查询的区间边界的设定。假设\(dx,dy\)分别为\(x,y\)离散化后的值,则我们求最大值时不能把左右边界算在内。
对于\(dx\),若其恰好在左边界上,则查询时须加\(1\),否则其位置必大于左边界,无需加\(1\)。
对于\(dy\),若其恰好在有边界上,则查询时须减\(1\),否则其位置必大于右边界,同需减\(1\)。可得结论,\(dy\)必减\(1\)。
在确保不是\(false\)的前提下,考虑如果是\(Maybe\),有\(2\)种情况:
- 左边界降雨量未知或右边界降雨量未知。
- 左右边界间存在降雨量未知。
其中第\(2\)种情况我们可以通过比较左右边界离散化前后的差值是否一样,从而进行判断。
如果不是\(false\)也不是\(maybe\),则自然就是\(true\)。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 50000
#define max(x,y) ((x)>(y)?(x):(y))
#define GetPos(x) (lower_bound(s+1,s+n+1,data(x))-s)
#define Maybe {puts("maybe");continue;}
#define False {puts("false");continue;}
#define True {puts("true");continue;}
using namespace std;
int n;
struct data
{
int Year,Rain;I data(CI x=0,CI y=0):Year(x),Rain(y){}
I bool operator < (Con data& t) const {return Year^t.Year?Year<t.Year:Rain<t.Rain;}
}s[N+5];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
int f;char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0,f=1;W(!D) f=c^'-'?1:-1;W(x=tn+(c&15),D);x*=f;}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
}F;
class RMQ//RMQ求区间最值
{
private:
static const int SZ=N,Log=16;int Log2[SZ+5],Max[SZ+5][Log+5];
public:
I void Init(CI n,data* s)//初始化
{
RI i,j;for(i=1;i<=n;++i) Max[i][0]=s[i].Rain;for(i=2;i<=n;++i) Log2[i]=Log2[i>>1]+1;
for(j=1;(1<<j)<=n;++j) for(i=1;i+(1<<j)<=n;++i) Max[i][j]=max(Max[i][j-1],Max[i+(1<<j-1)][j-1]);
}
I int GetMax(CI l,CI r) {if(l>r) return 0;RI k=Log2[r-l+1];return max(Max[l][k],Max[r-(1<<k)+1][k]);}//区间求Max
}R;
int main()
{
RI Qtot,i,x,y,dx,dy,dv;for(F.read(n),i=1;i<=n;++i) F.read(s[i].Year,s[i].Rain);//读入数据
R.Init(n,s),F.read(Qtot);W(Qtot--)//处理询问
{
F.read(x,y),dx=GetPos(x),dy=GetPos(y),dv=R.GetMax(s[dx].Year^x?dx:dx+1,dy-1);//读入x,y,dx,dy表示离散化后的位置,dv表示左右边界间的最大降雨量
if(!(s[dx].Year^x)&&s[dx].Rain<=dv) False;if(!(s[dy].Year^y)&&s[dy].Rain<=dv) False;//判断左、右边界的降雨量已知且小于等于左右边界间的最大降雨量的情况
if(!(s[dx].Year^x)&&!(s[dy].Year^y)&&s[dx].Rain<s[dy].Rain) False;//判断左、右边界降雨量皆已知且左边界降雨量小于右边界降雨量的情况
if(s[dx].Year^x||s[dy].Year^y||(y-x)^(dy-dx)) Maybe;True;//判断左边界降雨量未知或右边界降雨量未知或左右边界间存在降雨量未知的情况
}return 0;
}
【BZOJ1067】[SCOI2007] 降雨量(RMQ+分类讨论)的更多相关文章
- BZOJ1067 [SCOI2007]降雨量 RMQ???
求救!!!神犇帮我瞅瞅呗...未完...调了2个半小时线段树,没调出来,大家帮帮我啊!!! 小詹用st表写. 我的思路就是把中间空着的年份设为无限,然后一点点特判就行了...然而没出来... [SCO ...
- [BZOJ1067][SCOI2007]降雨量
[BZOJ1067][SCOI2007]降雨量 试题描述 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意 Y<Z<X,Z年的降雨量严格 ...
- 【BZOJ1067】[SCOI2007]降雨量 RMQ+特判
[BZOJ1067][SCOI2007]降雨量 Description 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年 ...
- bzoj1067——SCOI2007降雨量(线段树,细节题)
题目描述 我们常常会说这样的话:"X年是自Y年以来降雨量最多的".它的含义是X年的降雨量不超过Y年,且对于任意\(Y<Z<X\),Z年的降雨量严格小于X年.例如2002 ...
- 【线段树 细节题】bzoj1067: [SCOI2007]降雨量
主要还是细节分析:线段树作为工具 Description 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小 ...
- BZOJ1067 [SCOI2007]降雨量 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1067 题意概括 给定n组整数对(Xi,Yi),当Xi<Xj且Yi>=Yj时,如果对于任 ...
- 洛谷P2471 [SCOI2007] 降雨量 [RMQ,模拟]
题目传送门 降雨量 题目背景 07四川省选 题目描述 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X ...
- [bzoj1067][SCOI2007]降雨量——线段树+乱搞
题目大意 传送门 题解 我国古代有一句俗话. 骗分出奇迹,乱搞最神奇! 这句话在这道题上得到了鲜明的体现. 我的方法就是魔改版线段树,乱搞搞一下,首先借鉴了黄学长的建树方法,直接用一个节点维护年份的区 ...
- 【bzoj1067】[SCOI2007]降雨量 倍增RMQ
题目描述 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年.例如2002,2003,2004和200 ...
随机推荐
- esper(3)-窗口&聚合分组
一.Insert and Remove Stream 1. select * from com.ebc.updatelistener.User 只输出newEvents,不会输出oldEvents.即 ...
- 9 Strings
1 Strings 1.1 Strings and GStrings Groovy允许你使用2种不同类型的字符串类型,分别是java.lang.String和groovy.lang.GS ...
- Reactive Extensions入门
https://www.cnblogs.com/yangecnu/archive/2012/11/03/Introducting_ReactiveExtensions.html 前面我写过7篇文章粗略 ...
- Linux防火墙配置学习记录
一.iptables基本原理 1.iptables是一个管理内核包过滤的工具,包含4个表,5个链 表和链被称为Netfilter模块的两个维度, 表提供特定的功能内置四个表: filter表:用于对数 ...
- mapreduce求平均数
1. 现有某电商关于商品点击情况的数据文件,表名为goods_click,包含两个字段(商品分类,商品点击次数),分隔符“ ”,由于数据很大,所以为了方便统计我们只截取它的一部分数据,内容如下 ...
- Android 5.0以上heads up通知
适用Android系统: 1) Android版本>= 5.0 2) 部分ROM是不支持 RemoteViews view=getRemoteViews(body,title, R.mipmap ...
- 获取tomcat路径
String serverPath = System.getProperty("catalina.home");
- 使用eclipse IDE遇到的问题
Problems opening an editor Reason project name does not exist 项目右键->configure->convert to mave ...
- 17082 两个有序数序列中找第k小(优先做) O(logn)
17082 两个有序数序列中找第k小(优先做) 时间限制:1000MS 内存限制:65535K提交次数:0 通过次数:0 题型: 编程题 语言: G++;GCC;VC Description 已 ...
- Linux平台命令挂载U盘——实现数据共享
废话少说,一一道来,Linux中按照步骤来做就可以啦.(嵌入式平台) 1.先看看本地的mount信息 # mountrootfs on / type rootfs (rw)/dev/root on / ...