题目描述

我们常常会说这样的话:“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. Promise.resolve()与Promise

    //Promise.resolve()和Promise.reject()常用来生成已经被决议为失败或者成功的promise案例 //Promise.reject()简单一些,不管传给它什么值,它决议为 ...

  2. javascript 之迭代器

    简介 迭代器是一种设计模式,可在容器对象 如 链表.数组上遍历,无需关心容器对象的内存分配的实现细节.简单的理解就是可以一个一个的依次拿到其中的数据,类似一个移动的指针,但是会告诉我们什么时候结束.这 ...

  3. Servlet学习笔记(三)之HttpServletResponse

    init() 方法中参数 ServletConfig 对象使用 通过ServletConfig 获得 ServletContext对象 使用 HttpServletRequest 与HttpServl ...

  4. VS Code闪现,巨头纷纷入局的Web IDE缘何崛起?

    我发了,我装的. 就在前几天,微软简短的发布了Visual Studio Code for the Web 的公告,而没过一阵,这则公告就被删除了,现在点经相关内容已经是404状态了.虽然公告的内容已 ...

  5. Linux - last 命令(Mac 电脑)

    前言 为啥写这篇? 因为听 grep.sed 教程的时候有这个命令栗子 加上工作中,运维给我排查问题的时候也用到了,感觉挺重要,先了解为敬! 命令作用 显示用户和TTY的最后登录次数 这个是在 Mac ...

  6. JDK7u21反序列化详解

    目录 前言 环境 倒序分析 TemplatesImpl AnnotationInvocationHandler HashMap 总结 前言 听说jdk7u21的反序列化涉及的知识量很多,很难啃,具体来 ...

  7. javascript对象——基本对象

    1.array对象 2.Boolean包装类对象和Date对象   3.Math对象 1到100随机数 4.RegExp对象 4.1 正则规则 如: 4.2 两种创建正则对象方式 /正则表达式/    ...

  8. shell编程之条件语句

    目录: 一.条件测试 1.test命令测试 2.文件测试 3.字符串比较 4.逻辑测试 二.if语句 1.if单分支语句 2.if双分支语句 3.if多分支语句 三.case语句 case多分支语句 ...

  9. 【多线程】Android多线程学习笔记——线程池

    Java线程池采用了享元设计模式,在系统中维持一定数量的线程,用于处理异步或并发需求,在平时处理异步或并发任务时被广泛使用.这里基于JDK1.8和Android28来整理一些关于线程池的知识点. 一. ...

  10. Dapr实战(二) 服务调用

    服务调用是什么 在分布式应用程序中的服务之间进行调用会涉及到许多挑战. 例如: 维护其他服务的地址. 如何安全地调用服务. 在发生短暂的 暂时性错误 时如何处理重试. 分布式应用程序调用链路追踪. 服 ...