poj2452(RMQ+二分)

题目链接:POJ - 2452

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=50010;
 7 
 8 int qmax[maxn][30],qmin[maxn][30];
 9 int a[maxn];
10 int MIN(int x,int y) //返回下标
11 {
12     if(a[x]<a[y]) return x;
13     else return y;
14 }
15 int MAX(int x,int y)//返回下标
16 {
17     if(a[x]>a[y]) return x;
18     else return y;
19 }
20 void INIT_RMQ(int n)
21 {
22     int k=log2(n);
23     for(int i=0;i<=n;i++)
24         qmax[i][0]=qmin[i][0]=i;
25     for(int j=1;j<=k;j++)
26         for(int i=1;i+(1<<j)-1<=n;i++)
27     {
28         qmax[i][j]=MAX(qmax[i][j-1],qmax[i+(1<<j-1)][j-1]);
29         qmin[i][j]=MIN(qmin[i][j-1],qmin[i+(1<<j-1)][j-1]);
30     }
31     return;
32 }
33 
34 int rmqmax(int x,int y)
35 {
36     int k=log2(y-x+1);
37     return MAX(qmax[x][k],qmax[y-(1<<k)+1][k]);
38 }
39 int rmqmin(int x,int y)
40 {
41     int k=log2(y-x+1);
42     return MIN(qmin[x][k],qmin[y-(1<<k)+1][k]);
43 }
44 int BIN(int id,int l,int r)
45 {
46     while(l<=r)
47     {
48         if(l==r) return l;
49         int m=(l+r)>>1;
50         if(a[rmqmin(l,m)]>a[id]) l=m+1; 
51         else r=m;
52     }
53 }
54 int main()
55 {
56         int n;
57         while(scanf("%d",&n)!=EOF)
58         {
59             for(int i=1;i<=n;i++)
60                 scanf("%d",&a[i]);
61             INIT_RMQ(n);
62             int ans=0;//二分
63             for(int i=1;i+ans<n;i++)
64             {
65                 int r=BIN(i,i+1,n);
66                 int k=rmqmax(i,r);
67                 if(a[k]>a[i]) ans=max(ans,k-i);
68             }
69             if(ans==0) puts("-1");
70             else printf("%d
",ans);
71         }
72 }