1. 程式人生 > >Gym - 101911B Glider(字首和+二分)

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">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 x

x2 (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(1n210^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 122=10

In the second example the glider can fly from (16,10) to (34,0), and the distance is 3416=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\n",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
*/