zoukankan      html  css  js  c++  java
  • 【BZOJ 1067】 [SCOI2007]降雨量

    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

     
    线段树显然,考虑各种情况
    有一种总是忘了,当不存在末尾年份时,若存在比开头年份降雨量还大的年份就是false
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=50010;
     6 int n,m,l,r,mx,cnt;
     7 int year[N],w[N];
     8 struct tree{int l,r,mx,lch,rch;}tr[N*2];
     9  
    10 void build(int k,int l,int r){
    11     int mid=(l+r)>>1;
    12     tr[++cnt].l=l,tr[cnt].r=r;
    13     if(l==r) return;
    14     tr[k].lch=cnt+1;build(cnt+1,l,mid);
    15     tr[k].rch=cnt+1;build(cnt+1,mid+1,r);
    16 }
    17  
    18 void ins(int k,int x){
    19     int mid=(tr[k].l+tr[k].r)>>1,lc=tr[k].lch,rc=tr[k].rch;
    20     if(tr[k].l==tr[k].r){tr[k].mx=w[x];return;}
    21     if(x>mid) ins(rc,x);else ins(lc,x);
    22     tr[k].mx=max(tr[lc].mx,tr[rc].mx);
    23 }
    24  
    25 int query_max(int k,int l,int r){
    26     if(l>r) return 0;
    27     int mid=(tr[k].l+tr[k].r)>>1,lc=tr[k].lch,rc=tr[k].rch;
    28     if(tr[k].l==l&&tr[k].r==r) return tr[k].mx;
    29     if(r<=mid) return query_max(lc,l,r);
    30     else if(l>mid) return query_max(rc,l,r);
    31     else return max(query_max(lc,l,mid),query_max(rc,mid+1,r));
    32 }
    33  
    34 int main(){
    35     scanf("%d",&n);
    36     build(1,1,n);
    37     for(int i=1;i<=n;i++) scanf("%d%d",&year[i],&w[i]),ins(1,i);
    38     scanf("%d",&m);
    39     for(int i=1;i<=m;i++){
    40         scanf("%d%d",&l,&r);
    41         if(r==year[1]||l==year[n]) {printf("maybe
    ");continue;} 
    42         int x=lower_bound(year+1,year+1+n,l)-year;
    43         int y=lower_bound(year+1,year+1+n,r)-year;
    44         int xx=(year[x]==l),yy=(year[y]==r);
    45         if(!xx&&!yy) {printf("maybe
    ");continue;}
    46         if(!xx&&yy){
    47             mx=query_max(1,x,y-1);
    48             if(mx<w[y]) printf("maybe
    ");else printf("false
    ");
    49             continue; 
    50         }
    51         if(xx&&!yy){
    52             mx=query_max(1,x+1,y-1);
    53             if(mx<w[x]) printf("maybe
    ");else printf("false
    ");
    54             continue;
    55         }
    56         if(xx&&yy) {
    57             if(w[x]<w[y]) {printf("false
    ");continue;};
    58             mx=query_max(1,x+1,y-1);
    59             if(mx>=w[y]){printf("false
    ");continue;}
    60             if((y-x)!=(year[y]-year[x])) {printf("maybe
    ");continue;}
    61             printf("true
    ");   
    62         }
    63     }
    64 } 
  • 相关阅读:
    《数据结构第一章复习》
    《图的基本操作》
    《矩阵的一些基本操作》
    <矩阵的基本操作:矩阵相加,矩阵相乘,矩阵转置>
    《两个二维数组(矩阵)相乘》
    C#隐藏与显示系统任务栏和开始菜单栏按钮
    C#通过窗体属性缩小一定尺寸时,无法再缩小窗体尺寸问题
    C#一个窗体调用另一个窗体的方法
    C#异步线程
    C#中MessageBox.Show问题(让提示窗口不显示在任务栏中)
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5202606.html
Copyright © 2011-2022 走看看