题目描述

我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意\(Y<Z<X\),Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未知,有的说法是可能正确也可以不正确的。

输入输出格式

输入格式:

输入仅一行包含一个正整数n,为已知的数据。以下n行每行两个整数\(yi\)和\(ri\),为年份和降雨量,按照年份从小到大排列,即\(yi<yi+1\)。下一行包含一个正整数m,为询问的次数。以下m行每行包含两个数Y和X,即询问“X年是自Y年以来降雨量最多的。”这句话是必真、必假还是“有可能”。

输出格式:

对于每一个询问,输出true,false或者maybe。

简单来说!对于一个询问来说\(x,y\),我们需要满足\(x\ge y>z 其中z\in[x+1,y-1]\)

一眼看过去QwQ

这个题难道不是区间维护最大值,不就OK了吗?

一写,发现完美gg!!

进入正题:

首先我们发现年份是非常大的,所以需要将离散化,同时又方便我们统计有没有未知的年份\(maybe\)的

那么我们就从小到大依次将年份标号为\(1 - n\),然后如果当前的年份比前一个年份大1以上,那么就将给他赋一个1的权值

那么我们统计两个年份之间有没有未知的年的时候,我们需要求一个区间和,就可以得知了

接下来是处理询问,首先我们要知道询问种给定的两个年份不一定是都知道的

那么我们应该怎么判断这个年份是不是知道的呢?

只需要开一个数组,记录所有出现的年份,然后\(lower_bound\)一下,看一下和它本身一不一样就行了

int getpos(int x)
{
if (x<ss[1]) return ss[1];
if (x>ss[n]) return ss[n];
return ss[lower_bound(ss,ss+1+n,x)-ss];
}

所以需要分类讨论:

当$x!=getpos(x) 且 y!=getpos(y) \(的时候,一定是\)maybe$

当$x==getpos(x) 且 y!=getpos(y) $的时候,我们需要把y跳到第一个已知的年(就是比他小的最大的)

if (y>ss[n]) y=ss[n];
else
y=ss[lower_bound(ss,ss+1+n,y)-ss-1];

然后比较中间的数,是否都小于x,如果存在大于等于的x的年份,那一定是\(false\)否则就是\(maybe\)

当\(x!=getpos(x) 且 y==getpos(y)\)的时候,同理

当\(x==getpos(x) 且 y==getpos(y)\)的时候

我们就是要满足\(x\ge y>z 其中z\in[x+1,y-1]\)就可以,那么求一个中间区间的最大值,然后比较一下就可以

如果中间区间的query不等于区间长度,那就是maybe

我建议,就是先判断\(false\)接着判断\(true\)else就是\(maybe\)

一些细节之间看代码吧

上代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<map>
#include<vector> using namespace std; inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
} const int maxn = 300010; struct Node{
int mx,mn;
int sum;
}; Node f[4*maxn];
int n,m;
int a[maxn];
int c[maxn]; void up(int root)
{
f[root].mx=max(f[2*root].mx,f[2*root+1].mx);
f[root].mn=min(f[2*root].mn,f[2*root+1].mn);
f[root].sum=f[2*root].sum+f[2*root+1].sum;
} void build(int root,int l,int r)
{
if (l==r)
{
f[root].mn=f[root].mx=a[l];
f[root].sum=c[l];
return;
}
int mid = (l+r) >> 1;
build(2*root,l,mid);
build(2*root+1,mid+1,r);
up(root);
} int querymax(int root,int l,int r,int x,int y)
{
if (l>r || x>y) return -2e9;
if (x<=l && r<=y)
{
return f[root].mx;
}
int mid = (l+r) >> 1;
int ans = -2e9;
if (x<=mid) ans=max(ans,querymax(2*root,l,mid,x,y));
if (y>mid) ans=max(ans,querymax(2*root+1,mid+1,r,x,y));
return ans;
} int querysum(int root,int l,int r,int x,int y)
{
if (l>r || x>y) return 0;
if (x<=l && r<=y)
{
return f[root].sum;
}
int mid = (l+r) >> 1;
int ans = 0;
if (x<=mid) ans+=querysum(2*root,l,mid,x,y);
if (y>mid) ans+=querysum(2*root+1,mid+1,r,x,y);
return ans;
} int front;
int ss[maxn]; int getpos(int x)
{
if (x<ss[1]) return ss[1];
if (x>ss[n]) return ss[n];
return ss[lower_bound(ss,ss+1+n,x)-ss];
} int get(int x)
{
if (x<ss[1]) return 1;
if (x>ss[n]) return n;
return lower_bound(ss,ss+1+n,x)-ss;
} int main()
{
scanf("%d",&n);
c[1]=1;
for (int i=1;i<=n;i++)
{
int x,y;
scanf("%d",&x);
scanf("%d",&a[i]);
if (i!=1 && x-front==1) c[i]=1;
ss[i]=x;
front=x;
}
ss[++n]=2e9; ss[0]=-2e9;
build(1,1,n); scanf("%d",&m);
// cout<<querymax(1,1,n,2,4)<<endl;
for (int i=1;i<=m;i++)
{
int x,y;
x=read(),y=read();
if (x!=getpos(x) && y!=getpos(y))
{
printf("maybe\n");
continue;
}
if (x!=getpos(x))
{
x=getpos(x);
int a1=querymax(1,1,n,get(x),get(y)-1);
int cnt = a[get(y)];
if (a1>=cnt) printf("false\n");
else printf("maybe\n");
continue;
}
if (y!=getpos(y))
{
if (y>ss[n]) y=ss[n];
else
y=ss[lower_bound(ss,ss+1+n,y)-ss-1];
int a1=querymax(1,1,n,get(x)+1,lower_bound(ss,ss+1+n,y)-ss);
//cout<<a1<<endl;
int cnt = a[get(x)];
if (a1>=cnt) printf("false\n");
else printf("maybe\n");
continue;
}
int l=get(x)+1,r=get(y);
int cnt = a[get(y)];
int cnt1=a[get(x)];
int a1=querymax(1,1,n,get(x)+1,get(y)-1);
int a3=querysum(1,1,n,get(x)+1,get(y));
if (a1>=cnt || cnt>cnt1) printf("false\n");
else if (a1<cnt && r-l+1==a3 && cnt<=cnt1) printf("true\n");
else printf("maybe\n");
}
return 0;
}

bzoj1067——SCOI2007降雨量(线段树,细节题)的更多相关文章

  1. BZOJ1067&P2471 [SCOI2007]降雨量[线段树裸题+细节注意]

    dlntqlwsl 很裸的一道线段树题,被硬生生刷成了紫题..可能因为细节问题吧,我也栽了一次WA50分.不过这个隐藏条件真的对本菜鸡来说不易发现啊. 未知的年份连续的就看成一个就好了,把年份都离散化 ...

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

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

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

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

  4. [SCOI2007]降雨量 线段树和区间最值(RMQ)问题

      这道题是比较经典的 \(RMQ\) 问题,用线段树维护是比较简单好写的.比较难的部分是判断处理.如果没有想好直接打代码会调很久(没错就是我).怎么维护查询区间最大值我就不再这里赘述了,不懂线段树的 ...

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

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

  6. 【2019.10.7 CCF-CSP-2019模拟赛 T2】绝对值(abs)(线段树细节题)

    找规律 设\(p_i=a_{i+1}-a_i\),则答案就是\(\sum_{i=1}^{n-1}p_i\). 考虑若将\(a_i\)加上\(x\)(边界情况特殊考虑),就相当于是将\(p_{i-1}\ ...

  7. hdu-5023线段树刷题

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

  8. poj-2777线段树刷题

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

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

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

  10. [BZOJ1067][SCOI2007]降雨量

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

随机推荐

  1. reids rdb与aof

    rdb:时合高并发场景,容易备份恢复,会丢失部分数据 1.默认开启的方式,可以进过压缩,可以根据时间点生成快照 2.数据量大的情况下恢复快 3.bgsave一边开启fork保存文件,一边继续响应客户端 ...

  2. Java - 记录01_开发环境搭建

    时间:2017-07-04 记录:byzqy 一.什么是JDK JDK(Java Development Kit):Java开发工具集,即Java语言的软件开发工具包. SDK(Software De ...

  3. 分数化循环小数C++实现

    引言 前一阵做了一个有理数四则混合运算的程序(详见:用C++实现的有理数(分数)四则混合运算计算器),以分数形式呈现运算结果.这次添加以循环小数形式呈现运算结果的功能.例如: Please input ...

  4. centos7 wget安装jdk

    2021-07-151. 环境介绍 操作系统:centos7 jdk版本:jdk1.8.0.211 2. 下载 进入 https://www.oracle.com/java/technologies/ ...

  5. 用GUI实现java版贪吃蛇小游戏

    项目结构 新建一个JFrame窗口,作为程序入口 public class GameStart{ public static void main(String[] args) { JFrame jFr ...

  6. OpenCV 之 透视 n 点问题

    透视 n 点问题,源自相机标定,是计算机视觉的经典问题,广泛应用在机器人定位.SLAM.AR/VR.摄影测量等领域 1  PnP 问题 1.1  定义 已知:相机的内参和畸变系数:世界坐标系中,n 个 ...

  7. Week2 题解

    T1及题解 T2 CF1207E 首先,异或这个位运算有个很好的性质:x^y^y=x 于是,可以有两种解决方法: 法一 既然让猜原来的数是多少,当它异或了一个其他值val的时候,再异或val就会变回原 ...

  8. (5)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Boot简介

    ​Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是简化新 Spring 应用的初始搭建以及开发过程.该框架使用了特定的方式进行配置,从而使开发人员不再需要定义样板化的配置 ...

  9. %v的使用

    不同的类型,他们的默认的%v     一个变动的格式化字符串,相当于一个变量,遇到不同类型,就变形成不同的格式. 类型 %v bool %t int/int8/... %d uint/uint8/.. ...

  10. 【PHP数据结构】图的遍历:深度优先与广度优先

    在上一篇文章中,我们学习完了图的相关的存储结构,也就是 邻接矩阵 和 邻接表 .它们分别就代表了最典型的 顺序存储 和 链式存储 两种类型.既然数据结构有了,那么我们接下来当然就是学习对这些数据结构的 ...