点此看题面

大致题意:请你判断“\(x\)年是自\(y\)年以来降雨量最多的”这句话的真假。

离散化/\(lower\_bound\)

首先,考虑到年份的范围非常大,便可以离散化。

而我比较懒,反正题目中说了年份是递增的,因此我直接用了\(C++\)自带的\(lower\_bound\)。

\(RMQ\)

这题还需要使用的一个算法便是\(RMQ\)。

这应该是一个比较基础的算法吧,这里就不多加介绍了。

至于哪里需要使用,后面你就知道了。

分类讨论

考虑如果是\(false\),则无非有\(3\)种情况:

  1. 左边界的降雨量已知且小于等于左右边界间的最大降雨量。
  2. 右边界的降雨量已知且小于等于左右边界间的最大降雨量。
  3. 左、右边界降雨量皆已知且左边界降雨量小于右边界降雨量。

这里要求区间最大降雨量,就需要使用前面提到过的\(RMQ\)了。

注意\(RMQ\)查询的区间边界的设定。假设\(dx,dy\)分别为\(x,y\)离散化后的值,则我们求最大值时不能把左右边界算在内。

对于\(dx\),若其恰好在左边界上,则查询时须加\(1\),否则其位置必大于左边界,无需加\(1\)。

对于\(dy\),若其恰好在有边界上,则查询时须减\(1\),否则其位置必大于右边界,同需减\(1\)。可得结论,\(dy\)必减\(1\)。

在确保不是\(false\)的前提下,考虑如果是\(Maybe\),有\(2\)种情况:

  1. 左边界降雨量未知或右边界降雨量未知。
  2. 左右边界间存在降雨量未知。

其中第\(2\)种情况我们可以通过比较左右边界离散化前后的差值是否一样,从而进行判断。

如果不是\(false\)也不是\(maybe\),则自然就是\(true\)。

代码

  1. #include<bits/stdc++.h>
  2. #define Tp template<typename Ty>
  3. #define Ts template<typename Ty,typename... Ar>
  4. #define Reg register
  5. #define RI Reg int
  6. #define Con const
  7. #define CI Con int&
  8. #define I inline
  9. #define W while
  10. #define N 50000
  11. #define max(x,y) ((x)>(y)?(x):(y))
  12. #define GetPos(x) (lower_bound(s+1,s+n+1,data(x))-s)
  13. #define Maybe {puts("maybe");continue;}
  14. #define False {puts("false");continue;}
  15. #define True {puts("true");continue;}
  16. using namespace std;
  17. int n;
  18. struct data
  19. {
  20. int Year,Rain;I data(CI x=0,CI y=0):Year(x),Rain(y){}
  21. I bool operator < (Con data& t) const {return Year^t.Year?Year<t.Year:Rain<t.Rain;}
  22. }s[N+5];
  23. class FastIO
  24. {
  25. private:
  26. #define FS 100000
  27. #define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
  28. #define tn (x<<3)+(x<<1)
  29. #define D isdigit(c=tc())
  30. int f;char c,*A,*B,FI[FS];
  31. public:
  32. I FastIO() {A=B=FI;}
  33. Tp I void read(Ty& x) {x=0,f=1;W(!D) f=c^'-'?1:-1;W(x=tn+(c&15),D);x*=f;}
  34. Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
  35. }F;
  36. class RMQ//RMQ求区间最值
  37. {
  38. private:
  39. static const int SZ=N,Log=16;int Log2[SZ+5],Max[SZ+5][Log+5];
  40. public:
  41. I void Init(CI n,data* s)//初始化
  42. {
  43. 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;
  44. 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]);
  45. }
  46. 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
  47. }R;
  48. int main()
  49. {
  50. 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);//读入数据
  51. R.Init(n,s),F.read(Qtot);W(Qtot--)//处理询问
  52. {
  53. 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表示左右边界间的最大降雨量
  54. if(!(s[dx].Year^x)&&s[dx].Rain<=dv) False;if(!(s[dy].Year^y)&&s[dy].Rain<=dv) False;//判断左、右边界的降雨量已知且小于等于左右边界间的最大降雨量的情况
  55. if(!(s[dx].Year^x)&&!(s[dy].Year^y)&&s[dx].Rain<s[dy].Rain) False;//判断左、右边界降雨量皆已知且左边界降雨量小于右边界降雨量的情况
  56. if(s[dx].Year^x||s[dy].Year^y||(y-x)^(dy-dx)) Maybe;True;//判断左边界降雨量未知或右边界降雨量未知或左右边界间存在降雨量未知的情况
  57. }return 0;
  58. }

【BZOJ1067】[SCOI2007] 降雨量(RMQ+分类讨论)的更多相关文章

  1. BZOJ1067 [SCOI2007]降雨量 RMQ???

    求救!!!神犇帮我瞅瞅呗...未完...调了2个半小时线段树,没调出来,大家帮帮我啊!!! 小詹用st表写. 我的思路就是把中间空着的年份设为无限,然后一点点特判就行了...然而没出来... [SCO ...

  2. [BZOJ1067][SCOI2007]降雨量

    [BZOJ1067][SCOI2007]降雨量 试题描述 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意 Y<Z<X,Z年的降雨量严格 ...

  3. 【BZOJ1067】[SCOI2007]降雨量 RMQ+特判

    [BZOJ1067][SCOI2007]降雨量 Description 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年 ...

  4. bzoj1067——SCOI2007降雨量(线段树,细节题)

    题目描述 我们常常会说这样的话:"X年是自Y年以来降雨量最多的".它的含义是X年的降雨量不超过Y年,且对于任意\(Y<Z<X\),Z年的降雨量严格小于X年.例如2002 ...

  5. 【线段树 细节题】bzoj1067: [SCOI2007]降雨量

    主要还是细节分析:线段树作为工具 Description 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小 ...

  6. BZOJ1067 [SCOI2007]降雨量 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1067 题意概括 给定n组整数对(Xi,Yi),当Xi<Xj且Yi>=Yj时,如果对于任 ...

  7. 洛谷P2471 [SCOI2007] 降雨量 [RMQ,模拟]

    题目传送门 降雨量 题目背景 07四川省选 题目描述 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X ...

  8. [bzoj1067][SCOI2007]降雨量——线段树+乱搞

    题目大意 传送门 题解 我国古代有一句俗话. 骗分出奇迹,乱搞最神奇! 这句话在这道题上得到了鲜明的体现. 我的方法就是魔改版线段树,乱搞搞一下,首先借鉴了黄学长的建树方法,直接用一个节点维护年份的区 ...

  9. 【bzoj1067】[SCOI2007]降雨量 倍增RMQ

    题目描述 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年.例如2002,2003,2004和200 ...

随机推荐

  1. Appium——appium之mac环境安装

    一.安装brew:Homebrew是一款Mac OS平台下的软件包管理工具执行:/usr/bin/ruby -e "$(curl -fsSL https://raw.githubuserco ...

  2. Laravel5.1接收json数据

    <?php namespace App\Http\Controllers;use Illuminate\Routing\Controller as BaseController; use Ill ...

  3. Java字符串拆分和字符串连接

    Java字符串拆分/连接 public class LierString{ //------------------------------------------------------------ ...

  4. java——数组栈 ArrayStack

    栈的应用: undo操作-编辑器 系统调用栈-操作系统 括号匹配-编译器 以下是动态数组实现的数组栈: 定义动态数组: package Date_pacage; public class Array& ...

  5. 转 python trace walk DEMO

    https://blog.csdn.net/steadfast123/article/details/46965125 #quote from 'introduction to computation ...

  6. DEDE图集手工上传图片,加入水印

    DEDE的图集手工上传图片,是一个非常好用的flash上传图片工具.但是如果我们希望上传的图片,带有自己网站指定的水印,却发现没有达到我们的要求--那么如果我们确实希望上传的图片,带有水印,怎么办?以 ...

  7. 用java实现删除文件夹里的所有文件

    package com.org.improve.contact; import java.io.File; public class DeletePaper { /** * @param args * ...

  8. .NET通过PowerShell操作ExChange为用户开通邮箱教程

    转:http://www.cnblogs.com/gongguo/archive/2012/03/12/2392049.html =================================== ...

  9. C#委托(一)——说明及举例

    C#命名空间下有五种类型,分别为: 类.构造.接口.枚举.委托. 委托被定义为5中基本类型的一种,也就意味着代码可以这么写: using System; namespace Test { delega ...

  10. iOS 8 提供 TestFlight 方便开发者测试软件 (转)

    原文地址:http://tech2ipo.com/66893 TestFlight / via iMore 作者: Nick Arnott   译者:翛凌 原文:iMore  iOS 应用程序的测试对 ...