Problem:
Score : 600 points

Problem Statement

Silver Fox is fighting with N monsters.

The monsters are standing in a row, and we can assume them to be standing on a number line. The i-th monster, standing at the coordinate X_i, has the health of H_i.

Silver Fox can use bombs to attack the monsters.
Using a bomb at the coordinate x decreases the healths of all monsters between the coordinates x-D and x+D (inclusive) by A.
There is no way other than bombs to decrease the monster's health.

Silver Fox wins when all the monsters' healths become 0 or below.

Find the minimum number of bombs needed to win.

Constraints

1 \leq N \leq 2 \times 10^5

0 \leq D \leq 10^9

1 \leq A \leq 10^9

0 \leq X_i \leq 10^9

1 \leq H_i \leq 10^9

X_i are distinct.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N D A
X_1 H_1
:
X_N H_N

Output

Print the minimum number of bombs needed to win.

Sample Input 1

3 3 2
1 2
5 4
9 2

Sample Output 1

2

First, let us use a bomb at the coordinate 4 to decrease the first and second monsters' health by 2.

Then, use a bomb at the coordinate 6 to decrease the second and third monsters' health by 2.

Now, all the monsters' healths are 0.
We cannot make all the monsters' health drop to 0 or below with just one bomb.

Sample Input 2

9 4 1
1 5
2 4
3 3
4 2
5 1
6 2
7 3
8 4
9 5

Sample Output 2

5

We should use five bombs at the coordinate 5.

Sample Input 3

3 0 1
300000000 1000000000
100000000 1000000000
200000000 1000000000

Sample Output 3

3000000000

Watch out for overflow.

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

static class Program
{
    class PriorityQueue<T>
    {
        private readonly List<T> m_list;
        private readonly Comparison<T> m_compare;
        public int Count { get; private set; }
        public PriorityQueue(Comparison<T> compare)
        {
            m_list = new List<T>();
            m_compare = compare;
            Count = 0;
        }
        private int Add(T value)
        {
            if (Count == m_list.Count)
            {
                m_list.Add(value);
            }
            else
            {
                m_list[Count] = value;
            }
            return Count++;
        }
        private void Swap(int a, int b)
        {
            T tmp = m_list[a];
            m_list[a] = m_list[b];
            m_list[b] = tmp;
        }
        public void Enqueue(T value)
        {
            int c = Add(value);
            while (c > 0)
            {
                int p = (c - 1) / 2;
                if (m_compare(m_list[c], m_list[p]) < 0) { Swap(p, c); } else { break; }
                c = p;
            }
        }
        public T Dequeue()
        {
            T value = m_list[0];
            m_list[0] = m_list[--Count];
            int p = 0;
            while (true)
            {
                int c1 = p * 2 + 1;
                int c2 = p * 2 + 2;
                if (c1 >= Count) { break; }
                int c = (c2 >= Count || m_compare(m_list[c1], m_list[c2]) < 0) ? c1 : c2;
                if (m_compare(m_list[c], m_list[p]) < 0) { Swap(p, c); } else { break; }
                p = c;
            }
            return value;
        }
    }

    class Monster
    {
        public readonly long X;
        public readonly long H;
        public Monster(long[] args)
        {
            X = args[0];
            H = args[1];
        }
    }

    static long Solve(long N, long D, long A, Monster[] monsters)
    {
        var q = new PriorityQueue<Tuple<long, int, long>>((a, b) => (a.Item1 == b.Item1) ? a.Item2.CompareTo(b.Item2) : a.Item1.CompareTo(b.Item1));
        foreach (var m in monsters)
        {
            q.Enqueue(Tuple.Create(m.X, 0, m.H));
        }
        long cnt = 0;
        long sum = 0;
        while (q.Count > 0)
        {
            var t = q.Dequeue();
            switch (t.Item2)
            {
            case 0:
                long H = Math.Max(t.Item3 - sum, 0);
                long n = (H + A - 1) / A;
                cnt += n;
                sum += n * A;
                q.Enqueue(Tuple.Create(t.Item1 + D * 2, 1, n * A));
                break;
            case 1:
                sum -= t.Item3;
                break;
            }
        }
        return cnt;
    }

    static void Main(string[] args)
    {
        var V = Array.ConvertAll(Console.ReadLine().Split(), long.Parse);
        long N = V[0], D = V[1], A = V[2];
        var monsters = new Monster[N];
        for (int i = 0; i < N; ++i)
        {
            monsters[i] = new Monster(Array.ConvertAll(Console.ReadLine().Split(), long.Parse));
        }
        Console.WriteLine(Solve(N, D, A, monsters));
    }
}