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

    跨越大半年的更新

    题目链接(点我)

    题面描述

    我们常常会说这样的话:“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年以来降雨量最多的。”这句话是必真、必假还是“有可能”。

    输出格式

    对于每一个询问,输出truefalse或者maybe

    做法:

    假设年降水量为w[i]

    x,y为所求年份,l,r为其所对应的坐标,z=max(w[l+1~r-1])

    由于输入的时候保证年份递增,因此没有必要离散化吧。。。

    接下来就是分类讨论

    if(x&&z>=x) false;

    if(y&&z>=y) false;

    if(x&&y),x<y false;

    else

    if(x&&y&&l-r+1==y-x-1) true;

    else maybe;

    最大值采用线段树维护,l,r采用二分查找,详见代码:

    代码:

    #include<bits/stdc++.h>
    #define mid (l+r)/2
    using namespace std;
    const int N=5e4+10;
    int a[N],w[N],n;
    int t[N<<2];
    void build(int i,int l,int r){
        if(l==r){
            t[i]=w[l];
            return ;
        }
        build(2*i,l,mid);
        build(2*i+1,mid+1,r);
        t[i]=max(t[2*i],t[2*i+1]);
    }
    int query(int i,int l,int r,int L,int R){
        if(L>R) return -1e9;
        if(l>=L&&r<=R)
            return t[i];
        int ret=0;
        if(L<=mid) ret=max(ret,query(2*i,l,mid,L,R));
        if(R>mid) ret=max(ret,query(2*i+1,mid+1,r,L,R));
        return ret;
    }
    int main(){
        int q;
        scanf("%d",&n);
        a[0]=1e9+7,a[n+1]=-(1e9+7);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&a[i],&w[i]);
        build(1,1,n);
        scanf("%d",&q);
        while(q--){
            int x,y;
            scanf("%d%d",&x,&y);
            int l=lower_bound(a+1,a+n+1,x)-a;while(a[l]<=x) l++;
            int r=lower_bound(a+1,a+n+1,y)-a;while(a[r]>=y) r--;
            int z=query(1,1,n,l,r);
            if((a[r+1]==y&&z>=w[r+1])||(a[l-1]==x&&z>=w[l-1])||(a[l-1]==x&&a[r+1]==y&&w[l-1]<w[r+1])) puts("false");
            else{
                 if(r-l+1==y-x-1&&a[l-1]==x&&a[r+1]==y) puts("true");
                 else puts("maybe");
            }
        }
        return 0;
    }

     

    自己选择的路,跪着也要走完
  • 相关阅读:
    2021,6,10 xjzx 模拟考试
    平衡树(二)——Treap
    AtCoder Beginner Contest 204 A-E简要题解
    POJ 2311 Cutting Game 题解
    Codeforces 990G GCD Counting 题解
    NOI2021 SDPTT D2T1 我已经完全理解了 DFS 序线段树 题解
    第三届山东省青少年创意编程与智能设计大赛总结
    Luogu P6042 「ACOI2020」学园祭 题解
    联合省选2021 游记
    Codeforces 1498E Two Houses 题解 —— 如何用结论吊打标算
  • 原文地址:https://www.cnblogs.com/tonyshen/p/14008465.html
Copyright © 2011-2022 走看看