2021 CCPC 哈尔滨题解

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
你为什么在搜题解!
抓起来!
请添加图片描述

猜你喜欢

转载自blog.csdn.net/qq_45673816/article/details/121582620