这道B题,刚的不行,各种碎点及其容易忽略,受不鸟了直接

1067: [SCOI2007]降雨量

Time Limit: 1 Sec Memory Limit: 162 MB

Submit: 2859 Solved: 735

[Submit][Status][Discuss]

Description

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

Input

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

Output

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

Sample Input

6

2002 4920

2003 5901

2004 2832

2005 3890

2007 5609

2008 3024

5

2002 2005

2003 2005

2002 2007

2003 2007

2005 2008

Sample Output

false

true

false

maybe

false

HINT

100%的数据满足:1<=n<=50000, 1<=m<=10000, -10^9<=yi<=10^9, 1<=ri<=10^9

Source

POJ 2637 WorstWeather Ever

这道题,理性的来分析一下(遇到这种题,和我谈理性??)
先给出一些年份的信息,然后给出一些年份对,求解
不难想到线段树来维护一下区间最值(其实ST表编起来快多了)
由数据看出需要离散,当然输入人性化排序给出,所以不是很难,只需要开个struct数组来保存各个年份区间,建树相对繁琐...
然后分类讨论下结果:
先设两个端点年份为X,Y;题目需要满足r【x】<=r【y】,且任意X<Z<Y都满足,r【Z】<【Y】; TRUE:
两个端点数值已知,且左端点数值小于等于右端点数值,两端点间各年份都已知,且数值都小于右端点数值
MAYBE:
1.两个端点数值都已知,且左端点数值小于等于右端点数值,中间有未知年份,且已知年份数值皆小于右端点数值
2.左端点有值,右端点无值,中间端点随意了
3.左端点无值,右端点无值,中间端点更随意
4.左端点无值,右端点有值,中间端点允许有未知年份,但已知年份数值小于右端点数值
5.右端点为已知端点的第一个or左端点为已知端点的最后一个
FALSE:
不是false的都讨论完了,剩下的只能是false了,不满足上述种种的直接false掉! 说起来,第一次写需要struct存储和操作的线段树,写起来确实不是很习惯QAQ.....
感谢友善的黄学长在我迷茫时给我的交谈,开导ORZ

下面是代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 50010
struct data{
int l,r,maxr;
bool know;
};
data rain[maxn<<2]; void updataknow(int now)
{
rain[now].know=rain[now<<1].know && rain[now<<1|1].know;
}//向上更新区间各年份是否都存在这一信息 void updatamaxr(int now)
{
rain[now].maxr=max(rain[now<<1].maxr,rain[now<<1|1].maxr);
}//更新区间最大降雨量 void build(int now,int l,int r)
{
if (l==r)
{
int x,y;
scanf("%d%d",&x,&y);
rain[now].l=rain[now].r=x;
rain[now].maxr=y;
rain[now].know=true;
return;
}//添加点的值
int mid=(l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
updataknow(now);
if (rain[now<<1].r+1!=rain[now<<1|1].l)//如果两个区间相结合,若左子区间的最后年份+1不等于右子区间的最先年份,则根区间不全
rain[now].know=false;
rain[now].l=rain[now<<1].l;rain[now].r=rain[now<<1|1].r;//更新跟区间的最早最晚年份
updatamaxr(now);
}//建树 int getpoint(int now,int loc)
{
if (rain[now].l==rain[now].r)
if (rain[now].l!=loc)
return 0;
else
return rain[now].maxr;
if (loc<=rain[now<<1].r)
return getpoint(now<<1,loc);
else
if (loc>=rain[now<<1|1].l)
return getpoint(now<<1|1,loc);
return 0;
}//获取点的值 ,如果此点不存在返回0 int askquery(int L,int R,int now,int data)//返回值为1表示端点不是最大,2表示都已知且都小于端点,3表示存在未知但已知的都小于端点
{
bool f=false;//判断询问是否超界(这道题中,易望点1)
if (L<rain[now].l)
{
L=rain[now].l;
f=true;
}//先判断查询区间是否超过 最大区间
if (L==rain[now].l && R==rain[now].r)
{
if (rain[now].maxr>=data) return 1;//如果区间最大值比端点数值大,就返回1
else if (rain[now].know==true && f==false) return 2;//如果全都已知且不超界且小于端点返回2
else return 3;//有未知的东东或者超界了但已知的都大于端点就返回3
}
if (R<=rain[now<<1].r) return askquery(L,R,now<<1,data);//如果询问区间全都在左子区间返回与左子区间的关系
else if (L>=rain[now<<1|1].l) return askquery(L,R,now<<1|1,data);//同上讨论与右子区间关系
else
{
int x=askquery(L,rain[now<<1].r,now<<1,data);
int y=askquery(rain[now<<1|1].l,R,now<<1|1,data);
if (x==1 || y==1) return 1;//有一半比端点要大,就返回1
else if (rain[now<<1].r+1!=rain[now<<1|1].l) return 3;//左子区间的最大年份+1若不等于右子区间最小年份返回3
else return 2;//其余返回2
}//查询区间在两个子区间之间
}//查询此区间与数值的关系 int former(int now,int loc)
{
if (rain[now].l==rain[now].r) return rain[now].l;
else if (loc>rain[now<<1|1].l) return former(now<<1|1,loc);
else return former(now<<1,loc);
}//求loc的前一个存在具体值的年份(可以为本身) int latter(int now,int loc)
{
if (rain[now].l==rain[now].r) return rain[now].l;
else if (loc<rain[now<<1].r) return latter(now<<1,loc);
else return latter(now<<1|1,loc);
}//求loc的后一个存在具体值的年份(亦可以为本身) int main()
{
int n,m;
scanf("%d",&n);
build(1,1,n);
scanf("%d",&m);
for (int i=1; i<=m; i++)
{
int x,y;
scanf("%d%d",&x,&y);
int a=getpoint(1,x),b=getpoint(1,y);//a表示查询区间左端点的值,b表示右端点的值
if (a==0 && b==0) puts("maybe");//a和b都未知==>maybe
else
{
int left=latter(1,x),right=former(1,y);//left表示左端点后面有值的第一个点,right则是右端点前面有值的第一个点
if (a==0)//假使只有左端点未知
{
if (left>right || y==right) {puts("maybe");continue;}
if (askquery(left,right,1,b)==1) puts("false");//left和right之间值比右端点值大==>false
else puts("maybe");
}
else if (b==0)//假使只有右端点未知
{
if (left>right || x==left) {puts("maybe");continue;}
if (askquery(left,right,1,a)==1) puts("false");//同上述
else puts("maybe");
}
else//左右端都已知
{
if (b>a) {puts("false");continue;}//左端值小于右端值==>false
if (left>right)
if (x+1==y) {puts("true");continue;}
else {puts("maybe");continue;}
if (askquery(left,right,1,b)==1) {puts("false");continue;}
else if (askquery(left,right,1,b)==2)
if (left==x+1 && right==y-1) {puts("true");continue;}
else {puts("maybe");continue;}
else if (askquery(left,right,1,b)==3) puts("maybe");
else {puts("false");continue;}
}
} }
return 0;
}

BZOJ-1067 降雨量 线段树+分类讨论的更多相关文章

  1. bzoj 3779 重组病毒 好题 LCT+dfn序+线段树分类讨论

    题目大意 1.将x到当前根路径上的所有点染成一种新的颜色: 2.将x到当前根路径上的所有点染成一种新的颜色,并且把这个点设为新的根: 3.查询以x为根的子树中所有点权值的平均值. 分析 原题codec ...

  2. P5979 [PA2014]Druzyny dp 分治 线段树 分类讨论 启发式合并

    LINK:Druzyny 这题研究了一下午 终于搞懂了. \(n^2\)的dp很容易得到. 考虑优化.又有大于的限制又有小于的限制这个非常难处理. 不过可以得到在限制人数上界的情况下能转移到的最远端点 ...

  3. SPOJ 2916 Can you answer these queries V(线段树-分类讨论)

    题目链接:http://www.spoj.com/problems/GSS5/ 题意:给出一个数列.每次查询最大子段和Sum[i,j],其中i和j满足x1<=i<=y1,x2<=j& ...

  4. 美团CodeM初赛B轮 合并字符串的价值 (线段树,分类讨论)

    输入两个字符串a和b,合并成一个串c,属于a或b的字符在c中顺序保持不变.如"ACG"和"UT"可以被组合成"AUCTG"或"AC ...

  5. 2020牛客暑假多校训练营 第二场 H Happy Triangle set 线段树 分类讨论

    LINK:Happy Triangle 这道题很容易. 容易想到 a+b<x a<x<b x<a<b 其中等于的情况在第一个和第三个之中判一下即可. 前面两个容易想到se ...

  6. BZOJ 1067 降雨量(RMQ-ST+有毒的分类讨论)

    1067: [SCOI2007]降雨量 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 4399  Solved: 1182 [Submit][Stat ...

  7. BZOJ.4184.shallot(线段树分治 线性基)

    BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...

  8. [BZOJ 4025]二分图(线段树分治+带边权并查集)

    [BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...

  9. BZOJ 1067 降雨量

    Description 我们常常会说这样的话:"\(X\)年是自\(Y\)年以来降雨量最多的".它的含义是\(X\)年的降雨量不超过\(Y\)年,且对于任意\(Y<Z< ...

随机推荐

  1. Git版本控制工具(一)----git的安装及创建版本库

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  2. Jira-Clone与发邮件的使用

    1.克隆问题 包括两部分,先进行Clone,再进行移动 a.选择要克隆的问题,点击More Actions-Clone,在弹出框“复制问题”中,点击“创建”按钮即克隆成功 b.移动问题,点击More ...

  3. java 21 - 1 IO流中的字符流概述

    字节流通过读取一个byte数组的方式可以读取中文的,但是有可能出现小问题,所以,读取中文最好是用字符流. 字符流: 字符流=字节流+编码表. 编码表: 由字符及其对应的数值组成的一张表 编码表介绍: ...

  4. 转载 ---> UITableViewCell的分割线

    在iOS7中,表格中经常看到的一个情况是如下所示, 解决方法: 1,手写代码控制   1 self.tableView.separatorInset = UIEdgeInsetsMake(0, 0, ...

  5. R语言-merge和rbind

    rbind 使用方式 合并两个数据集,要求两个数据集的列数相等: rbind(parameter1,parameter2) 1 1 合并多个数据集,各个数据集的列数相等: rbind(paramete ...

  6. 【转】【Asp.Net】asp.net(c#) 网页跳转

    在asp.net下,经常需要页面的跳转,下面是具体的几种方法.跳转页面是大部编辑语言中都会有的,正面我们来分别介绍一下关于.net中response.redirect sever.execute se ...

  7. VMWare安装苹果操作系统OS X

    项目要求做一些简单的苹果开发尝试,由于苹果的各种开发要求在Macintosh机上进行,可是项目不值得为一次简单的尝试付出过多的购机费,所以只能另辟蹊径,跟别人学学怎么在虚拟机里面搞: http://j ...

  8. [iOS翻译]《iOS7 by Tutorials》系列:iOS7的设计精髓(上)

    简介: 本文翻译自<iOS7 by Tutorials>一书的第一章“Designing for iOS 7”,主要从程序员角度介绍了iOS7的新设计理念,堪称神作!本文翻译仅作学习交流之 ...

  9. Matlab 用fread、fwrite实现大文件读写

    最近在分析一个35G的大数据文件,猛一看,是不是很吓人啊,不过还好,师兄写文件的格式非常规范,读取数据来也就很方便了,主要是使用了读写文件的两个函数fread和fwrite,下面用matlab简单尝试 ...

  10. [CareerCup] 5.2 Binary Representation of Real Number 实数的二进制表示

    5.2 Given a real number between 0 and 1 (e.g., 0.72) that is passed in as a double, print the binary ...