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 }