Gym - 101911B Glider(前缀和+二分)

Posted esquecer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gym - 101911B Glider(前缀和+二分)相关的知识,希望对你有一定的参考价值。

传送门:点我

A plane is flying at a constant height of hh meters above the ground surface. Let‘s consider that it is flying from the point (?10^9,h)(?10^9,h) to the point (10^9,h)(10^9,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 xx1 and xx2 (x1<x2x1<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 11, he will stop at 1010. Otherwise, if he jumps out at 22, he will stop at 1212.

Determine the maximum distance along OxOx 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 00.

Input

The first line contains two integers nn and h(1n2?10^5,1h10^9)(1≤n≤2?10^5,1≤h≤10^9) — the number of ascending air flow segments and the altitude at which the plane is flying, respectively.

Each of the next nn lines contains two integers xi1xi1 and xi2xi2 (1xi1<xi210^9)(1≤xi1<xi2≤10^9) — the endpoints of the ii-th ascending air flow segment. No two segments intersect, and they are given in ascending order.

Output

Print one integer — the maximum distance along OxOx 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

NOTE

In the first example if the glider can jump out at (2,4), then the landing point is (12,0), so the distance is 12?2=10

In the second example the glider can fly from (16,10) to (34,0), and the distance is 34?16=18

In the third example the glider can fly from (?100,1000000000) t(1999999899,0), so the distance is 1999999899?(?100)=1999999999

大概题意:

给出的是n个气流带(按顺序给出),和你现在所在的高度m。在气流带中不会下降,即维持进入气流带的高度。不在气流带则会每次下降一个单位。

下面n行是气流带的起点和终点。注意如果高度为0,恰好到下一个气流带的起点,也不能经过下一个加速带。

询问的是,起点的x值可以任你选择,最后降落下来到地面的点,离你选择起点的最远距离是多少。

因为是可以任意选起点,所以会有一个最大值。题目插图画的就是样例1的示例。

思路:看到题目给2秒,大暴力二分找?。算了下复杂度是O(NlogN),n是2e5,也可以接受。

           首先,要明确的一点是,起点肯定是某个加速带的起点,因为这样才能保证有更多的空间,留给后面经过更多的加速带(简单的贪心)

   其次,既然是二分,那么肯定要是有序的,在这题我二分的是从我选定的起点,最远到能到的终点,中间可以经过多少加速带。因为距离是递增的,所以可以二分。

     即,把每个加速带中间的间隔,抽取出来作为一个数组,对这个数组进行二分,然后同时维护一个本身加速带的长度的一个前缀和,用来快速计算,经过加速带的距离。

     最后答案肯定是 :能经过的加速带的距离+m   这个值的最大值

不知道还有没有更好的办法呀,还想学习一下。

暂时先这样子吧。

最后是代码:

#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
struct note{
    int x,y;
}p[200010];
int a[200010];
int main()
{
    vector<int>v;
    int sum = 0,cnt = 0,n,m;
    a[cnt++] = 0;//a数组维护加速带的前缀和 
    scanf("%d %d",&n,&m);
    for(int i = 0 ; i < n ; i ++){
        scanf("%d %d",&p[i].x,&p[i].y);
        a[cnt] = a[cnt-1] + p[i].y - p[i].x;
        cnt++;
        if(i > 0){
            sum += p[i].x-p[i-1].y;
            v.push_back(sum);
        }//v向量用来保存加速带的前缀和
    }
    int ans = 0;
    for(int i = 0 ;i <= v.size(); i++){
        int  pos = lower_bound(v.begin(),v.end(),(i==0?0:v[i-1])+m)-v.begin();
        sum = a[pos+1]-a[i] + m;//加速带的长度+m ,即要更新的答案 
        ans = max(sum,ans);
    }
    printf("%d
",ans);
}
/*
3 4
2 5
7 9
10 11

5 10
5 7
11 12
16 20
25 26
30 33

1 1000000000
1 1000000000
*/

 












以上是关于Gym - 101911B Glider(前缀和+二分)的主要内容,如果未能解决你的问题,请参考以下文章

F - Fabricating Sculptures Gym - 102428F (dp + 前缀和维护)

gym102889J线段树维护最大最小前缀和判断合法括号序列

Gym 101142 I.Integral Polygons 计算几何 奇偶性 前缀和

Gym101138D Strange Queries 莫队前缀和容斥

gym102222KVertex Covers(高维前缀和,meet in the middle)

Gym 100247CVictor's Research(有多少区间之和为S)