BZOJ1067: [SCOI2007]降雨量

$n \leq 50000$天的天气预报已知,其他未知,$m \leq 10000$个询问每次问:第$x$天和第$y$天是否满足,第$y$天降雨量$\leq$第$x$天,且不存在$x<z<y$使得第$z$天降雨量$\geq$第$y$天降雨量,输出一定,不可能或有可能。其他数字$\leq 1e9$。天可以负数。

镇站之宝路过。。

求区间最大用ST表。把未知天的降雨量设成$inf$,找某天降雨量时用二分,然后一顿特判。注意如果$y$未知,但$x$已知,而且有个$z$的降雨量$\geq$ $x$的降雨量,也是不合法的。

 1 //#include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 //#include<map>
 6 #include<math.h>
 7 //#include<time.h>
 8 //#include<complex>
 9 #include<algorithm>
10 using namespace std;
11 
12 int n,m;
13 #define maxn 100011
14 int a[maxn],val[maxn],la,inf=0x3f3f3f3f;
15 int rmq[maxn][22],rmq2[maxn][22],Log[maxn];
16 int query2(int x,int y)
17 {
18     if (x>y) return -inf;
19     int l=Log[y-x+1]; return max(rmq2[x][l],rmq2[y-(1<<l)+1][l]);
20 }
21 int query(int x,int y)
22 {
23     int l=Log[y-x+1];
24     return max(rmq[x][l],rmq[y-(1<<l)+1][l]);
25 }
26 int main()
27 {
28     scanf("%d",&n);
29     la=1; a[1]=-inf; val[1]=inf;
30     for (int i=1;i<=n;i++)
31     {
32         la++; scanf("%d%d",&a[la],&val[la]);
33         if (val[la-1]!=inf && a[la-1]!=a[la]-1)
34         {
35             a[la+1]=a[la]; val[la+1]=val[la];
36             a[la]=a[la-1]+1; val[la]=inf; la++;
37         }
38     } la=la; la++; a[la]=a[la-1]+1; val[la]=inf;
39     for (int i=1;i<=la;i++) if (val[i]==inf) val[i]=-inf;
40     for (int i=1;i<=la;i++) rmq2[i][0]=val[i];
41     for (int j=1;j<=18;j++)
42         for (int i=1,to=la-(1<<j)+1;i<=to;i++)
43             rmq2[i][j]=max(rmq2[i][j-1],rmq2[i+(1<<(j-1))][j-1]);
44     for (int i=1;i<=la;i++) if (val[i]==-inf) val[i]=inf;
45     for (int i=1;i<=la;i++) rmq[i][0]=val[i];
46     for (int j=1;j<=18;j++)
47         for (int i=1,to=la-(1<<j)+1;i<=to;i++)
48             rmq[i][j]=max(rmq[i][j-1],rmq[i+(1<<(j-1))][j-1]);
49     Log[0]=-1; for (int i=1;i<=la;i++) Log[i]=Log[i>>1]+1;
50     scanf("%d",&m);
51     while (m--)
52     {
53         int x,y; scanf("%d%d",&x,&y);
54         x=upper_bound(a+1,a+1+la,x)-a-1; y=upper_bound(a+1,a+1+la,y)-a-1;
55         if (val[y]!=inf && val[y]>val[x]) puts("false");
56         else if (query2(x+1,y-1)>=min(val[x],val[y])) puts("false");
57         else if (query(x,y)==inf) {puts("maybe");}
58         else puts("true");
59     }
60     return 0;
61 }
View Code

 

posted @ 2018-03-07 12:44  Blue233333  阅读(159)  评论(0编辑  收藏  举报