这道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. Unity Sample Bootcamp

    M4枪 射击特效 Gun.js源码 function GenerateGraphicStuff(hit : RaycastHit) { var hitType : HitType; var body ...

  2. [3D跑酷] UI事件处理系统

    在我们的Unity游戏项目中,GUI的表现采用NGUI.记录一下我们的处理方式: 需要解决的问题 1.需要处理大量按钮的点击事件 2.需要处理界面跳转事件 3.需要处理界面元素更新事件 解决方案 GU ...

  3. java 15- 5 List集合

    需求 1:List集合存储字符串并遍历.(步骤跟Collection集合一样,只是最初创建集合对象中的集合类改变了,Collection变成List) List集合的特点: 有序(存储和取出的元素一致 ...

  4. css3高级运动keyframes

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. typicalapp.js

    /** * 1.找出数字数组中最大的元素(使用Math.max函数) 2.转化一个数字数组为function数组(每个function都弹出相应的数字) 3.给object数组进行排序(排序条件是每个 ...

  6. Groovy Spock环境的安装

    听说spock是一个加强版的Junit,今天特地安装了,再把过程给大家分享一下. 首先说明,我的Java项目是用maven管理的. 我用的Eclipse是Kelper,开普勒. 要使用Spock之前, ...

  7. google project tango 学习笔记

    google io 2015上 project tango 的演示视频

  8. Contains Duplicate II

    Given an array of integers and an integer k, find out whether there there are two distinct indices i ...

  9. WCF4.0 –- RESTful WCF Services (1) (入门)

    WCF 很好的支持了 REST 的开发, 而 RESTful 的服务通常是架构层面上的考虑. 因为它天生就具有很好的跨平台跨语言的集成能力,几乎所有的语言和网络平台都支持 HTTP 请求,无需去实现复 ...

  10. 关于java按位操作运算

    <1>.在了解位移之前,先了解一下正数和负数的二进制表示形式以及关系:举例15和-15:15 的原码: 00000000 00000000 00000000 00001111     补码 ...