K 线段树上二分
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<climits>
using namespace std;
void File(){
freopen("B.in","r",stdin);
freopen("B.out","w",stdout);
}
#define REP(i,a,b) for(register int i=a;i<=b;++i)
#define DREP(i,a,b) for(register int i=a;i>=b;--i)
#define MREP(i,x) for(register int i=beg[x];i;i=E[i].last)
#define ll long long
#define inf INT_MAX
const int maxn=50000+10;
int n,lenth[maxn],height[maxn],ans=inf;
struct Segment_Tree{
#define mid ((l+r)>>1)
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define lc rt<<1
#define rc rt<<1|1
int Min[maxn<<2];
void build(int rt,int l,int r){
if(l==r){Min[rt]=height[l];return;}
build(lson);build(rson);
Min[rt]=min(Min[lc],Min[rc]);
}
int queryl(int rt,int l,int r,int L,int R,int x){
if(l==r)return Min[rt]<x ? l : 0;
if(L<=l && r<=R){
if(Min[rc]<x)return queryl(rson,L,R,x);
else return queryl(lson,L,R,x);
}
else{
int ret=0;
if(L<=mid)ret=max(ret,queryl(lson,L,R,x));
if(R>=mid+1)ret=max(ret,queryl(rson,L,R,x));
return ret;
}
}
int queryr(int rt,int l,int r,int L,int R,int x){
if(l==r)return Min[rt]<x ? l : n+1;
if(L<=l && r<=R){
if(Min[lc]<x)return queryr(lson,L,R,x);
else return queryr(rson,L,R,x);
}
else{
int ret=n+1;
if(L<=mid)ret=min(ret,queryr(lson,L,R,x));
if(R>=mid+1)ret=min(ret,queryr(rson,L,R,x));
return ret;
}
}
}T;
int main(){
File();
int posl[maxn]={0},posr[maxn]={0};
while(1){
ans=-inf;
scanf("%d",&n);
if(n==-1)return 0;
REP(i,1,n)scanf("%d%d",&lenth[i],&height[i]);
REP(i,2,n)posl[i]=posl[i-1]+lenth[i-1];
REP(i,1,n)posr[i]=posl[i]+lenth[i];
T.build(1,1,n);
int left,right;
REP(i,1,n){
left=1;right=n;
if(i!=1)left=T.queryl(1,1,n,1,i-1,height[i])+1;
if(i!=n)right=T.queryr(1,1,n,i+1,n,height[i])-1;
ans=max(ans,(posr[right]-posl[left])*height[i]);
}
printf("%d\n",ans);
}
return 0;
}
/*==========================
* Author : ylsoi
* Problem : Terrible Sets
* Algorithm : Segment_Tree
* Time : 2018.5.4
* ========================*/
poj2082
你为什么在搜题解!
抓起来!