首页 > 代码库 > POJ 2559 Largest Rectangle in a Histogram RMQ || 单调栈

POJ 2559 Largest Rectangle in a Histogram RMQ || 单调栈

题目链接:点击打开链接

题意就是求最大面积

枚举每个柱子作为起点

然后二分两边长度。 求个区间最值。

#include<stdio.h>
#include<iostream>
#include<math.h>
using namespace std;
#define ll long long
#define N 100100
inline bool rd(int &n){    
    int x = 0, tmp = 1;    
    char c = getchar();    
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();    
    if(c == EOF) return false;    
    if(c == '-') c = getchar(), tmp = -1;    
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();    
    n = x*tmp;    
    return true;  
}    
inline void pt(ll n){    
    if(n < 0)  
        putchar('-'), n = -n;    
    int len = 0,data[20];    
    while(n)    
        data[len++] = n%10, n /= 10;     
    if(!len) data[len++] = 0;    
    while(len--) putchar(data[len]+48);    
}  
int n;

int a[N];
int FMin[N][20];

void Init(){
    int i,j;
    for(i=1;i<=n;i++)
        FMin[i][0]=a[i];
    for(i=1;(1<<i)<=n;i++){   //按区间长度递增顺序递推
        for(j=1;j+(1<<i)-1<=n;j++){   //区间起点
            FMin[j][i]=min(FMin[j][i-1],FMin[j+(1<<(i-1))][i-1]);
        }
    }
}
int Query(int l,int r){
    int k=(int)(log(double(r-l+1))/log((double)2));
    return min(FMin[l][k],FMin[r-(1<<k)+1][k]);
}
int main() {
    while(rd(n), n){
		for(int i = 1; i <= n; i++) rd(a[i]);
        Init();
        ll ans = 0;
        for(int i = 1; i <= n; i++)
        {
			if(ans >= (ll)a[i]*n)continue;
            int l = 1, r = i-1, L = i;
            while(l<=r)
            {
                int mid = (l+r)>>1;
                if(Query(mid, i-1) >= a[i])
                    r = mid-1, L = min(L, mid);
                else
                    l = mid+1;
            }
            l = i+1, r = n; int R = i;
            while(l <= r)
            {
                int mid = (l+r)>>1;
                if(Query(i+1, mid) >= a[i])
                    l = mid+1, R = max(R, mid);
                else
                    r = mid-1;
            }
            ans = max(ans, (ll)(R-L+1) * a[i]);
        }
        pt(ans);putchar('\n');
    }
    return 0;
}