牛客网暑期ACM多校训练营(第二场) - G transform (二分)

https://www.nowcoder.com/acm/contest/140/G

优秀的题解

#include <iostream>
#include <stdio.h>
#include <string.h>
const int maxn = 500000+44;
#define LL long long
LL x[maxn],w[maxn];
LL precost[maxn],prew[maxn];
LL sufcost[maxn],sufw[maxn];
LL n,T;

LL cal_pre(LL l,LL r){
    return precost[r]-precost[l-1]-prew[l-1]*(x[r]-x[l-1]);
}

LL cal_suf(LL l,LL r){
    return sufcost[l]-sufcost[r+1]-sufw[r+1]*(x[r+1]-x[l]);
}

bool check(LL num)
{
    LL num2=num/2+1;
    LL l=1,r=1,mid=1;
    while(1){
        while(r<=n&&prew[r]-prew[l-1]<num) r++;
        while(mid<=n&&prew[mid]-prew[l-1]<num2) mid++;
        if(r>n||mid>n) break;
        LL s=cal_pre(l,mid)+cal_suf(mid,r-1)+(num-(prew[r-1]-prew[l-1]))*(x[r]-x[mid]);
        if(s<=T) return true;
        l++;
    }
    l=r=mid=n;
    while(1){
        while(l>=1&&prew[r]-prew[l-1]<num) l--;
        while(mid>=2&&prew[mid]-prew[l-1]<num2) mid--;
        if(l<1||mid<2) break;
        LL s=cal_pre(l+1,mid)+cal_suf(mid,r)+(num-(prew[r]-prew[l]))*(x[mid]-x[l]);
        if(s<=T) return true;
        r--;
    }
    return false;

}





int main(){
    scanf("%lld%lld",&n,&T);
    T/=2;
    for(LL i=1;i<=n;i++)   scanf("%lld",&x[i]);
    for(LL i=1;i<=n;i++)   scanf("%lld",&w[i]);
    for(LL i=1;i<=n;i++){
        prew[i]=prew[i-1]+w[i];
        precost[i]=precost[i-1]+prew[i-1]*(x[i]-x[i-1]);
    }
    LL r=0;
    for(LL i=n;i>=1;i--){
        sufw[i]=sufw[i+1]+w[i];
        sufcost[i]=sufcost[i+1]+sufw[i+1]*(x[i+1]-x[i]);
        r+=w[i];
    }
    LL l=0;
    while(l<r){
        LL mid = (l+r+1)>>1;
        if(check(mid)){
            l=mid;
        }else{
            r=mid-1;
        }
    }
    printf("%lld\n",l);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Mr_Treeeee/article/details/81183356
今日推荐