【BZOJ】【1067】 【SCOI2007】降雨量

思路题


  玛雅,这分类讨论快讨论地疯了……

  从huzecong神的题解那里得到的灵感……

  首先考虑最好确定的情况:为true的时候,此时必须同时满足

    1.x和y这两年的降雨量已知,且rain[x]<=rain[y]

    2.中间每一年的降雨量都已知,且降雨量的最大值小于rain[x]

  然后我们可以考虑一下为false的情况:(这两个条件满足其一即可)

    1.x和y这两年的降雨量已知,且rain[x]>rain[y]

    2.x和y这两年的降雨量只知其中之一,且中间这些年(已知的部分)最大的降雨量大于这个已知的x或y年的降雨量

  剩下的情况直接输出maybe

  但是如果你这么写你会发现你RE了= =,为什么呢?因为在x和y这两年的降雨量只知其中之一时,“中间年份“已知的可能一个也没有,也就是说我在进行中间这些年的降雨量的最大值的查询时会直接爆炸(我是用线段树来查询的)……所以需要在判false的第二种情况之前加上这一条:

    如果x和y中间没有其他年份,则输出maybe

然后我才AC掉……

 1 /**************************************************************
 2     Problem: 1067
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:164 ms
 7     Memory:3616 kb
 8 ****************************************************************/
 9  
10 //BZOJ 1067
11 #include<vector>
12 #include<cstdio>
13 #include<cstring>
14 #include<cstdlib>
15 #include<iostream>
16 #include<algorithm>
17 #define rep(i,n) for(int i=0;i<n;++i)
18 #define F(i,j,n) for(int i=j;i<=n;++i)
19 #define D(i,j,n) for(int i=j;i>=n;--i)
20 #define pb push_back
21 using namespace std;
22 inline int getint(){
23     int v=0,sign=1; char ch=getchar();
24     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
25     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
26     return v*sign;
27 }
28 const int N=1e5+10,INF=~0u>>2;
29 typedef long long LL;
30 /******************tamplate*********************/
31 int n,m,t[N<<2],year[N],rain[N];
32 #define L (o<<1)
33 #define R (o<<1|1)
34 #define mid (l+r>>1)
35 void build(int o,int l,int r){
36     if (l==r) t[o]=rain[l];
37     else{
38         build(L,l,mid);
39         build(R,mid+1,r);
40         t[o]=max(t[L],t[R]);
41     }
42 }
43 int ql,qr;
44 int query(int o,int l,int r){
45     if (ql<=l && qr>=r) return t[o];
46     else{
47         int ans=0;
48         if (ql<=mid) ans=max(ans,query(L,l,mid));
49         if (qr>mid) ans=max(ans,query(R,mid+1,r));
50         return ans;
51     }
52 }
53 int main(){
54 #ifndef ONLINE_JUDGE
55     freopen("1067.in","r",stdin);
56     freopen("1067.out","w",stdout);
57 #endif
58     n=getint();
59     F(i,1,n) year[i]=getint(),rain[i]=getint();
60     build(1,1,n);
61     m=getint();
62     int x,y,t1,t2;
63     F(i,1,m){
64         x=getint(); y=getint();
65         t1=upper_bound(year+1,year+n+1,x)-year;
66         t2=lower_bound(year+1,year+n+1,y)-year;
67         if (year[t2]==y && year[t1-1]==x && t1!=n+1 && t2!=n+1 &&
68             t2-t1==y-x-1 && rain[t2]<=rain[t1-1]){
69             ql=t1; qr=t2-1;
70             if (query(1,1,n)<rain[t2]) {puts("true");continue;}
71             else {puts("false");continue;}
72         }
73         if(year[t2]==y && year[t1-1]==x && rain[t2]>rain[t1-1])
74             {puts("false");continue;}
75         if(t2==t1){puts("maybe");continue;}
76         if(year[t2]==y && t2!=n+1){
77             ql=t1; qr=t2-1;
78             if (query(1,1,n)>=rain[t2]) {puts("false");continue;}
79         }
80         if(year[t1-1]==x && t1!=n+1){
81             ql=t1; qr=t2-1;
82             if (query(1,1,n)>=rain[t1-1]) {puts("false");continue;}
83         }
84         puts("maybe");
85     }
86     return 0;
87 }
View Code

1067: [SCOI2007]降雨量

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 2370  Solved: 613
[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

[Submit][Status][Discuss]
posted @ 2015-04-05 08:57  Tunix  阅读(196)  评论(0编辑  收藏  举报