zoukankan      html  css  js  c++  java
  • P2471 [SCOI2007]降雨量

    题目背景

    07四川省选

    题目描述

    我们常常会说这样的话:“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。

    输入输出样例

    输入样例#1: 
    6
    2002 4920
    2003 5901
    2004 2832
    2005 3890
    2007 5609
    2008 3024
    5
    2002 2005
    2003 2005
    2002 2007
    2003 2007
    2005 2008
    
    输出样例#1: 
    false
    true
    false
    maybe
    false
    

    说明

    100%的数据满足:1<=n<=50000, 1<=m<=10000, −109 <=yi<= 109 , 1<=ri<= 109

     

    Solution:

      本题题目出的是真的好()。。。`~`这两天调得我——快要吐血的万恶之源……

      首先我们对于判断时的输出顺序做一个调整,按情况的可能性从多到少,先判断$false$,再判断$maybe$,最后剩下的才是$true$。

      题目中会用到某段区间的最大值进行判断,所以我们可以用一棵线段树去维护(至于区间连续性就没必要用线段树维护了,有更好的方法,亏我开始傻乎乎用线段树去写`~`)。

      因为读入时的年份是保证递增的,所以对于每次询问$x,y$(当$xgeq y$直接输$false$),我们可以先二分找出第一个不小于$x$的位置,和$y$的位置,不妨假设为$st$和$ed$,然后判断边界的年份是否相等,并查询出$st+1$到$ed-1$的最大值(因为要取出中间一段的最大值,用其和两端比较,注意判断左端点年份不确定时要查询$st$到$ed-1$的最大值)。

      判断时:

        先判$false$:

          1、当右端点年份确定,且中间年份最大降雨量大于等于右端点降雨量  

          2、当左端点年份确定,且中间年份最大降雨量大于等于左端点降雨量 

          3、当左右端点年份都确定,且左端点降雨量小于等于右端点降雨量

        再判$maybe$:

          1、当左右端点之差不等于左右端点年份之差(等价于年份不连续,也就是我前面所说的更好的判断区间连续的方法)

          2、左端点年份不确定

          3、右端点年份不确定

          (因为已经切掉$false$的情况了,那么剩下的情况中可以直接照上面的判断!)

        最后若上面情况都不满足,那么肯定是$true$

       不得不说,本题很值得做,需要考虑很全面,至少我还不够稳,同时感谢巨佬$old-fish$提供的方法。

    代码:

    #include<bits/stdc++.h>
    #define il inline
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
    #define Max(a,b) ((a)>(b)?(a):(b))
    using namespace std;
    const int N=200005;
    int n,m,num[N],ls[N],rs[N];
    int ye[N],co[N];
    bool f[N];
    struct node{
        int ans,f;
    };
    
    il int gi(){
        int a=0;char x=getchar();bool f=0;
        while((x<'0'||x>'9')&&x!='-')x=getchar();
        if(x=='-')x=getchar(),f=1;
        while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();
        return f?-a:a;
    }
    
    il void pushup(int rt){
        if(rs[rt<<1]==ls[rt<<1|1]-1)f[rt]=f[rt<<1]&f[rt<<1|1];
        rs[rt]=rs[rt<<1|1];ls[rt]=ls[rt<<1];
        num[rt]=Max(num[rt<<1],num[rt<<1|1]);
    }
    
    il void build(int l,int r,int rt){
        if(l==r){rs[rt]=ls[rt]=ye[l],num[rt]=co[l],f[rt]=1;return;}
        int m=l+r>>1;
        build(lson),build(rson);
        pushup(rt);
    }
    
    il node query(int L,int R,int l,int r,int rt){
        if(L<=l&&R>=r){
            node tmp;
            tmp.ans=num[rt],tmp.f=f[rt];
            return tmp;
        }
        int m=l+r>>1;
        node tmp;
        tmp.ans=0,tmp.f=1;
        if(L<=m){
            node x=query(L,R,lson);
            tmp.ans=Max(tmp.ans,x.ans);
            tmp.f&=x.f;
        }
        if(R>m){
            node x=query(L,R,rson);
            tmp.ans=Max(tmp.ans,x.ans);
            tmp.f&=x.f;
        }
        return tmp;
    }
    
    int main(){
        n=gi();
        For(i,1,n)ye[i]=gi(),co[i]=gi();
        build(1,n,1);
        m=gi();
        int x,y;
        while(m--){
            x=gi(),y=gi();
            if(x>=y){printf("false
    ");continue;}
            int st=lower_bound(ye+1,ye+n+1,x)-ye,ed=lower_bound(ye+1,ye+n+1,y)-ye;
            bool fl,fr;int op=0;
            fl=ye[st]==x,fr=ye[ed]==y;
            if(!fl)st--;
            if(st+1<=ed-1)op=query(st+1,ed-1,1,n,1).ans;
            if((op>=co[ed]&&fr)||(co[st]<co[ed]&&fl&&fr)||(op>=co[st]&&fl))printf("false
    ");
            else if(ed-st!=ye[ed]-ye[st]||!fr||!fl)printf("maybe
    ");
            else printf("true
    ");
        }
        return 0;
    }
  • 相关阅读:
    开放的Web平台才是是我们想要的——HTML5变为HTML
    Web字体格式介绍及浏览器兼容性一览
    E百科 | 基于MEC的边缘AI服务
    技术改变生活 浅谈阿里云混合云的探索与实践
    阿里云CDN产品经理陈章炜:边缘创新技术和落地实践
    什么是微内核架构设计?
    技术干货 | 深度解构 Android 应用面临紧急发版时的救星方案:mPaaS 热修复——DexPatch
    如何接地气地接入微前端?
    阿里云原生应用安全防护实践与 OpenKruise 的新领域
    函数计算镜像加速:从分钟到秒的跨越
  • 原文地址:https://www.cnblogs.com/five20/p/9123773.html
Copyright © 2011-2022 走看看