P2471 [SCOI2007] 降雨量

[SCOI2007] 降雨量

题目描述

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

输入格式

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

输出格式

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

样例 #1

样例输入 #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 \le n \le 50000\)\(1 \le m \le 10000\)\(-10^9 \le y_i \le 10^9\)\(1 \le r_i \le 10^9\)\(-10^9 \le X, Y \le 10^9\)

数据保证 \(Y < X\)

solution:

读题真的是非常重要的一个好习惯:“它的含义是 \(X\) 年的降雨量不超过 \(Y\) 年,且对于任意 \(Y < Z < X\)\(Z\) 年的降雨量严格小于 \(X\) 年。”

读懂了这句话之后这题就好办了,我们维护一个动态开点线段树支持单点插入和区间查询,并且无修改

设每年的降雨量为\(w_i\)
然后我们对于每个询问(l,r)先查三个值:
w[l],w[r],和\(\forall i \in[l+1,r-1],\max w\)
那么一个询问的答案是ture的条件是:\(w[l] \ge w[r] > \max w\)且[l+1,r]是满的
如果满足前者但不满足后者,答案为maybe
如果l,r都不存在,那么显然是maybe
然后如果l,r有一个不存在并且存在的一方大于\(\max w\):也是maybe
如果上述条件都不成立,那么就是false了

Code:

#include<bits/stdc++.h>
const int N=1e5+5;
const int inf=1e9;
using namespace std;
map<int,int> Map;
int n,m,cnt,rt;
//Segment_Tree
struct Segment_Tree{
    int ls,rs,val,cnt;
}t[N*40];
void pushup(int x)
{
    t[x].val=max(t[t[x].ls].val,t[t[x].rs].val);
    t[x].cnt=t[t[x].ls].cnt+t[t[x].rs].cnt;
}
void insert(int &x,int y,int l,int r,int pos,int val)
{
    t[x=++cnt]=t[y];
    if(l==r)
    {
        t[x].val=val;
        t[x].cnt=1;
        return ;
    }
    int mid=l+r>>1;
    if(pos<=mid)insert(t[x].ls,t[y].ls,l,mid,pos,val);
    if(mid<pos)insert(t[x].rs,t[y].rs,mid+1,r,pos,val);
    pushup(x);
}
void query(int x,int l,int r,int L,int R,int &res,int &tot)
{
    if(!x)return;
    if(L<=l&&r<=R)
    {
        res=max(res,t[x].val);
        tot+=t[x].cnt;
        return ;
    }
    int mid=l+r>>1;
    if(L<=mid)query(t[x].ls,l,mid,L,R,res,tot);
    if(mid<R)query(t[x].rs,mid+1,r,L,R,res,tot);
}
void work()
{
    cin>>n;
    for(int i=1,t,w;i<=n;i++)
    {
        scanf("%d%d",&t,&w);
        insert(rt,rt,-inf,inf,t,w);
        Map[t]=w;
    }
    cin>>m;
    for(int i=1,l,r;i<=m;i++)
    {
        scanf("%d%d",&l,&r);
        int pre=0,mid=0,ans=0,tot=0;
        if(l+1<=r-1)
        query(rt,-inf,inf,l+1,r-1,mid,tot);
        tot=0;
        query(rt,-inf,inf,l+1,r,ans,tot);
        if(Map[l]>=Map[r]&&mid<Map[r]&&tot<r-l){printf("maybe\n");continue;}
        if(Map[l]>=Map[r]&&mid<Map[r]){printf("true\n");continue;}
        if(!Map[l]&&!Map[r]){printf("maybe\n");continue;}
        if(!Map[l]&&Map[r]>mid){printf("maybe\n");continue;}
        if(!Map[r]&&Map[l]>mid){printf("maybe\n");continue;}
        printf("false\n");
    }
}
int main()
{
    //freopen("P2471_1.in","r",stdin);
    //freopen("P2471.out","w",stdout);
    work();
    return 0;
}

posted @ 2024-11-11 19:03  liuboom  阅读(36)  评论(0)    收藏  举报