Problem:
D: 日焼け - Suntan -

物語

あいずにゃんは若ヶ松高校のプログラミングコンテスト部、通称ぷろこん部に所属する2年生である。天使のようにかわいい。
あいずにゃんは今年の夏フェスに参加する予定なので、聴きに行くバンドのスケジュールを立てた。
ここで心配なのが日焼けだ。
ライブはすべて野外で行われるが、あいずにゃんは日焼けしやすい体質なので長時間野外で紫外線を浴びすぎるとすぐ日焼けしてしまう。
ライブがない間は屋内に避難することでできるだけ紫外線を回避するつもりだが、ライブ中はどうしても日に当たってしまう。
そこであいずにゃんは日焼け止めを塗ることで紫外線対策をすることを考えた。

問題

日焼け止めを塗ると、塗った時間からT分間だけその効果を得ることができる。
日焼け止めは1回しか塗ることができないため、効果的に使いたい。
あいずにゃんは、ライブの開始時刻から終了時刻までは野外にいて、それ以外では屋内にいる。
あいずにゃんが聴く予定のライブスケジュールが与えられるので、野外にいる間で日焼け止めの効果を得られる最大の時間の長さを求めよ。

入力形式

入力は次の形式で与えらえる。

T
N
s_1 t_1
...
s_N t_N

1行目では日焼け止めの効果を得られる時間を表す整数Tが与えられる。
2行目ではあいずにゃんが聴くライブの数を表す整数Nが与えられる。
続くN行には、あいずにゃんがi番目に聴くライブの開始時刻を表す整数s_iと終了時刻を表す整数t_iが空白区切りで与えられる。

制約

1 ≤ T ≤ 10^{15}

1 ≤ N ≤ 10^5

0 ≤ s_i < t_i ≤ 10^{15} (1 ≤ i ≤ N)

(i+1)番目のライブの開始時刻はi番目のライブの終了時刻と同じかそれよりも遅い。すなわち、t_i ≤ s_{i+1} (1 ≤ i < N)

出力

野外にいる間で日焼け止めの効果を得られる最大の時間の長さを1行で出力せよ。

入力例1

20
1
0 10

出力例1

10

入力例2

20
1
0 100

出力例2

20

入力例3

9
3
1 5
9 11
13 20

出力例3

7

入力例4

25
5
9 12
15 20
21 25
28 40
45 60

出力例4

21

Solution in C# (judge verdict: Accepted)

using System.Collections.Generic;
using static System.Math;
using System;

public class hello
{
    public static long t;
    public static int n;
    public static void Main()
    {
        t = long.Parse(Console.ReadLine().Trim());
        n = int.Parse(Console.ReadLine().Trim());
        var a = new long[n];
        var a2 = new long[2 * n];
        var a3 = new long[n + 1];
        var p = 0;
        for (int i = 0; i < n; i++)
        {
            string[] line = Console.ReadLine().Trim().Split(' ');
            var w0 = long.Parse(line[0]);
            var w1 = long.Parse(line[1]);
            a[i] = w0;
            a2[p++] = w0; a2[p++] = w1;
            a3[i + 1] = a3[i] + w1 - w0;
        }
        var ans = getAns(a, a2, a3);
        Console.WriteLine(ans);
    }
    static long getAns(long[] a, long[] a2, long[] a3)
    {
        var ans = 0L;
        for (int i = 0; i < n; i++)
        {
            var w = a[i] + t;
            var w1 = LowerBound(a2, w);
            var w2 = getSum(a2, a3, i, w, w1);
            ans = Max(ans, w2);
        }
        return ans;
    }
    static long getSum(long[] a2, long[] a3, int i, long w, long w1)
    {
        var a2L = 2 * n;
        if (w1 == a2L) return a3[n] - a3[i];
        else if (a2[w1] == w && w1 % 2 == 0) return a3[w1 / 2 + 1] - a3[i] + 1;
        else if (a2[w1] == w && w1 % 2 == 1) return a3[(w1 - 1) / 2 + 1] - a3[i];
        else if (a2[w1] != w && w1 % 2 == 1) return a3[(w1 - 1) / 2] - a3[i] + w - a2[w1 - 1];
        else return a3[w1 / 2] - a3[i];
    }
    static int LowerBound<T>(T[] arr, int start, int end, T value, IComparer<T> comparer)
    {
        int low = start;
        int high = end;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (comparer.Compare(arr[mid], value) < 0)
                low = mid + 1;
            else
                high = mid;
        }
        return low;
    }
    static int LowerBound<T>(T[] arr, T value) where T : IComparable
    {
        return LowerBound(arr, 0, arr.Length, value, Comparer<T>.Default);
    }
}