题目链接:点击打开链接
题意就是求最大面积
枚举每个柱子作为起点
然后二分两边长度。 求个区间最值。
#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;
}