BZOJ1067&P2471 [SCOI2007]降雨量[线段树裸题+细节注意]

dlntqlwsl


很裸的一道线段树题,被硬生生刷成了紫题。。可能因为细节问题吧,我也栽了一次WA50分。不过这个隐藏条件真的对本菜鸡来说不易发现啊。

未知的年份连续的就看成一个就好了,把年份都离散化一下。

分四大类(设自X以来的Y年)

  1. X未知,Y未知.(maybe)
  2. X未知,Y已知.中间夹住的区间只看有没有超过Y降雨量的就行了(false/meybe)
  3. X已知,Y已知.看中间有没有超过的有就是false并且注意看X降雨量是不是大于等于Y的降雨量(来自题目第一行),其次再看中间最小值有没有0(我把未知的年份降雨量设为0),来判断false还是true
  4. X已知,Y未知.有坑!要看X到Y之间有没有超过X降雨量的,有的话Y没法满足条件。

错误笔记:栽在第4点上。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define l i<<1
 7 #define r i<<1|1
 8 #define dbg(x) cerr<<#x<<" = "<<x<<endl
 9 using namespace std;
10 typedef long long ll;
11 template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
12 template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
13 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
14 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
15 template<typename T>inline T read(T&x){
16     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
17     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
18 }
19 const int N=150000+7,inf=1e9;
20 int minv[N<<2],maxv[N<<2],A[N],year[N];
21 int n,m,q,nen,ryou,ql,qr,x,y,X,Y,minx,maxx;
22 void build(int i,int L,int R){
23     if(L==R){minv[i]=maxv[i]=A[L];return;}
24     int mid=L+R>>1;build(l,L,mid),build(r,mid+1,R);minv[i]=_min(minv[l],minv[r]);maxv[i]=_max(maxv[l],maxv[r]);
25 }
26 int Query_min(int i,int L,int R){
27     if(ql<=L&&qr>=R)return minv[i];
28     int mid=L+R>>1,ret=inf;
29     if(ql<=mid)MIN(ret,Query_min(l,L,mid));
30     if(qr>mid)MIN(ret,Query_min(r,mid+1,R));
31     return ret;
32 }
33 int Query_max(int i,int L,int R){
34     if(ql<=L&&qr>=R)return maxv[i];
35     int mid=L+R>>1,ret=0;
36     if(ql<=mid)MAX(ret,Query_max(l,L,mid));
37     if(qr>mid)MAX(ret,Query_max(r,mid+1,R));
38     return ret;
39 }
40 
41 int main(){//freopen("test.in","r",stdin);freopen("test.out","w",stdout);
42     read(n);year[0]=-inf-1;
43     for(register int i=1;i<=n;++i){
44         read(nen),read(ryou);
45         if(nen-1==year[m])year[++m]=nen,A[m]=ryou;
46         else ++m,year[m]=year[m-1]+1,year[++m]=nen,A[m]=ryou;
47     }
48     if(year[m]<inf)++m,year[m]=year[m-1]+1;
49     build(1,1,m);read(q);
50     while(q--){
51         read(x),read(y);
52         X=upper_bound(year+1,year+m+1,x)-year-1;
53         Y=upper_bound(year+1,year+m+1,y)-year-1;//dbg(X),dbg(Y),dbg(A[X]),dbg(A[Y]);
54         if(!A[X]){
55             if(X+1==Y||!A[Y])printf("maybe\n");
56             else{
57                 ql=upper_bound(year+1,year+m+1,x+1)-year-1;
58                 qr=upper_bound(year+1,year+m+1,y-1)-year-1;
59                 maxx=Query_max(1,1,m);
60                 if(maxx>=A[Y])printf("false\n");
61                 else printf("maybe\n");
62             }
63         }
64         else{
65             if(A[Y]>A[X]){printf("false\n");continue;}
66             if(!A[Y]){
67                 if(X+1==Y){printf("maybe\n");continue;}
68                 ql=upper_bound(year+1,year+m+1,x+1)-year-1;
69                 qr=upper_bound(year+1,year+m+1,y-1)-year-1;//dbg(ql),dbg(qr);
70                 maxx=Query_max(1,1,m);
71                 if(maxx>=A[X])printf("false\n");
72                 else printf("maybe\n");
73             }
74             else if(X+1==Y)printf("true\n");
75             else{
76                 ql=upper_bound(year+1,year+m+1,x+1)-year-1;
77                 qr=upper_bound(year+1,year+m+1,y-1)-year-1;//dbg(ql),dbg(qr);
78                 maxx=Query_max(1,1,m);minx=Query_min(1,1,m);//dbg(minx),dbg(maxx);
79                 if(maxx>=A[Y])printf("false\n");
80                 else if(!minx)printf("maybe\n");
81                 else printf("true\n");
82             }
83         }
84     }
85     return 0;
86 }

猜你喜欢

转载自www.cnblogs.com/saigyouji-yuyuko/p/10519989.html
今日推荐