CodeForces 1041D Glider 枚举+二分

题目链接:https://vjudge.net/problem/CodeForces-1041D/origin
题意:
飞行员在区间[-1e9,1e9]内(这个一定注意!!!),从高度为k处跳伞,会向右移动。
如果遇到上升气流,会水平向右移动,否则向右下方移动。
给定n端上升气流区间,不交叉不重叠。
问你最多移动多远。
先说整体思路,再说小细节。
观察可得,一般情况下,一定是从上升气流区间的左端点开始的,因为这样可以获得最大。
那么我们考虑枚举起点i(我们把上升区间和它右边的间隔区间看成一个整体,从1~n枚举),再用lower_bound查找第一个大于等于k的位置p。那么此时所移动的最大距离就是i到p的所有上升气流区间之和加上高度k(注意不是加上间隔区间之和!)。
我一开始感觉这样似乎就可以了,但是有几个问题没考虑到:
1、如果从某个起点i出发,到达边界1e9时,高度还没有降低为0,那么还可以看看i之前的区间能否再让它飞一段。所以先判断当前的k值大于剩下的间隔区间之和时,就往前找,并且不用lower_bound(因为找不到!)。
2、我们有n个上升气流区间,每个右边有一个间隔区间。如果考虑第一条的情况(详见样例3),就会出现bug,所以我们把第0个的上升区间看作[-1e9,-1e9],间隔区间为[-1e9,r],其中r为第一个上升区间的左端点。而且最后一个区间的右端点设置为[l,1e9],l为左端点
综上,这样的话就可以处理了。

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
#define sd(a) scanf("%d",&a)
#define sdd(a,b) scanf("%lld%lld",&a,&b)
#define cl(a,b) memset(a,b,sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define sddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define dbg() printf("aaa\n")
using namespace std;
const int maxn=2e5+10;
ll n,k;
struct node{//a是上升气流区间 b是空白区间
    ll l,r;
}a[maxn],b[maxn];
ll a1[maxn],b1[maxn];
int main() {
    sdd(n,k);
    a[0].l=-1000000000;
    a[0].r=-1000000000;
    a1[0]=0;
    rep(i,1,n){
        sdd(a[i].l,a[i].r);
        a1[i]=a[i].r-a[i].l;
    }
    b[0].l=-1000000000;
    b[0].r=a[1].l;
    b1[0]=b[0].r-b[0].l;
    rep(i,1,n-1){
        b[i].l=a[i].r;
        b[i].r=a[i+1].l;
        b1[i]=b[i].r-b[i].l;
    }
    b[n].l=a[n].r;
    b[n].r=1000000000;
    b1[n]=b[n].r-b[n].l;
    rep(i,1,n){
        a1[i]+=a1[i-1];
        b1[i]+=b1[i-1];
    }
    ll maxx=-1;
    rep(i,1,n){//枚举从第几个白色开始
        if(k>b1[n]-b1[i-1]){//若能飞过界
            ll now=b1[n]-b1[i-1]+a1[n]-a1[i-1];
            ll kk=k-(b1[n]-b1[i-1]);
            for(int j=i-1;j>=0;j--){
                if(kk<=b1[j]){
                    now+=kk;
                    break;
                }else{
                    now+=b1[j]+a1[j];
                    kk-=b1[j];
                }
            }
            maxx=max(maxx,now);
            break;
        }else{//k<b1[n]-b1[i-1]
            //注意这里做了修正!
            ll p=lower_bound(b1+i,b1+n+1,k+b1[i-1])-b1;
            maxx=max(maxx,a1[p]-a1[i-1]+k);
        }
    }
    printf("%lld\n",maxx);
    
    return 0;
}

A plane is flying at a constant height of h meters above the ground surface. Let’s consider that it is flying from the point (−109,h) to the point (109,h) parallel with Ox axis.

A glider is inside the plane, ready to start his flight at any moment (for the sake of simplicity let’s consider that he may start only when the plane’s coordinates are integers). After jumping from the plane, he will fly in the same direction as the plane, parallel to Ox axis, covering a unit of distance every second. Naturally, he will also descend; thus his second coordinate will decrease by one unit every second.

There are ascending air flows on certain segments, each such segment is characterized by two numbers x1 and x2 (x1<x2) representing its endpoints. No two segments share any common points. When the glider is inside one of such segments, he doesn’t descend, so his second coordinate stays the same each second. The glider still flies along Ox axis, covering one unit of distance every second.

If the glider jumps out at 1, he will stop at 10. Otherwise, if he jumps out at 2, he will stop at 12.
Determine the maximum distance along Ox axis from the point where the glider’s flight starts to the point where his flight ends if the glider can choose any integer coordinate to jump from the plane and start his flight. After touching the ground the glider stops altogether, so he cannot glide through an ascending airflow segment if his second coordinate is 0.

Input
The first line contains two integers n and h (1≤n≤2⋅105,1≤h≤109) — the number of ascending air flow segments and the altitude at which the plane is flying, respectively.

Each of the next n lines contains two integers xi1 and xi2 (1≤xi1<xi2≤109) — the endpoints of the i-th ascending air flow segment. No two segments intersect, and they are given in ascending order.

Output
Print one integer — the maximum distance along Ox axis that the glider can fly from the point where he jumps off the plane to the point where he lands if he can start his flight at any integer coordinate.

Examples
Input
3 4
2 5
7 9
10 11
Output
10
Input
5 10
5 7
11 12
16 20
25 26
30 33
Output
18
Input
1 1000000000
1 1000000000
Output
1999999999

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值