using System;
using System.Collections.Generic;
using System.Linq;
using static Input;
using static Prog;
using NX = System.Int64;

public class Solver
{
    public void Solve()
    {
        int N = NextInt();
        NX D = NextLong() * 2, A = NextLong();
        List<Tuple<NX, NX>> input = new List<Tuple<NX, NX>>();
        for (int i = 0; i < N; i++) { input.Add(new Tuple<NX, NX>(NextLong(), NextLong())); }
        var d = input.OrderBy(v => v.Item1).ToList();

        LazySegTree LST = new LazySegTree(N, 0, (x, y) => (x + y));
        for (int i = 0; i < N; i++) { LST.Insert(i, d[i].Item2); }

        NX ans = 0;
        for (int i = 0; i < N; i++)
        {
            if (LST.Query(i, i + 1) <= 0) continue;
            int ok = -1, ng = N;
            while (ng - ok != 1)
            {
                int mid = (ok + ng) / 2;
                if (d[mid].Item1 - d[i].Item1 <= D) ok = mid;
                else ng = mid;
            }
            //d[i].HP を超えるだけ打つ
            NX count = LST.Query(i, i + 1) / A + (LST.Query(i, i + 1) % A == 0 ? 0 : 1);
            //Console.WriteLine(d[i].Item1 + " -> " + d[ok].Item1 + " : " + count);
            ans += count;
            LST.InsertRange(i, ok + 1, -count * A);

        }
        Console.WriteLine(ans);
    }

}
public class LazySegTree
{
    private List<NX> node = new List<NX>();
    private List<NX> lazy = new List<NX>();
    private static int size = 1;
    private static NX lim;
    private static Func<NX, NX, NX> update_func;
    public LazySegTree(int n, NX m, Func<NX, NX, NX> func)
    {
        while (size < n) size *= 2;
        node = Enumerable.Range(0, 2 * size - 1).Select(v => m).ToList();
        lazy = Enumerable.Range(0, 2 * size - 1).Select(v => m).ToList();
        lim = m;
        update_func = func;
    }
    public void Insert(int pos, NX val)
    {
        pos += size - 1;
        node[pos] = val;
        while (pos != 0)
        {
            pos = (pos % 2 == 0 ? pos / 2 - 1 : pos / 2);
            node[pos] = update_func(node[pos * 2 + 1], node[pos * 2 + 2]);
        }
    }
    public void InsertRange(int ser_l, int ser_r, NX val, int index = 0, int now_l = 0, int now_r = 0)
    {
        if (2 * size < index) return;
        if (now_r <= now_l) now_r = size;
        Convey(index);
        if (ser_r <= now_l || now_r <= ser_l) return;
        if (ser_l <= now_l && now_r <= ser_r) { lazy[index] += (now_r - now_l) * val; Convey(index); }
        else
        {
            //Left
            InsertRange(ser_l, ser_r, val, index * 2 + 1, now_l, (now_l + now_r) / 2);
            //Reft
            InsertRange(ser_l, ser_r, val, index * 2 + 2, (now_l + now_r) / 2, now_r);
            node[index] = update_func(node[index * 2 + 1], node[index * 2 + 2]);
        }
    }


    public NX Query(int sel_l, int sel_r, int index = 0, int now_l = 0, int now_r = 0)
    {
        if (now_r <= now_l) now_r = size;
        if (now_r <= sel_l || sel_r <= now_l) return lim;
        Convey(index);
        if (sel_l <= now_l && now_r <= sel_r) { return node[index]; }
        NX left = Query(sel_l, sel_r, index * 2 + 1, now_l, (now_r + now_l) / 2);
        NX right = Query(sel_l, sel_r, index * 2 + 2, (now_r + now_l) / 2, now_r);
        return update_func(left, right);
    }
    void Convey(int index)
    {
        if (lazy[index] != 0)
        {
            node[index] += lazy[index];
            if (index < size - 1)
            {
                lazy[index * 2 + 1] += lazy[index] / 2;
                lazy[index * 2 + 2] += lazy[index] / 2;
            }
            lazy[index] = 0;
        }
    }
}

public class Prog
{
    public const long MOD = 1000000007;
    public const int INF = 1000000007;
    public struct Pair { public int x, y; public Pair(int a, int b) { x = a; y = b; } }
    static void Main()
    {
        var sw = new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
        Console.SetOut(sw);
        new Solver().Solve();
        Console.Out.Flush();
        return;
    }
}

public class Input
{
    private static Queue<string> q = new Queue<string>();
    private static void Confirm() { if (q.Count == 0) foreach (var s in Console.ReadLine().Split(' ')) q.Enqueue(s); }
    public static int NextInt() { Confirm(); return int.Parse(q.Dequeue()); }
    public static long NextLong() { Confirm(); return long.Parse(q.Dequeue()); }
    public static string NextString() { Confirm(); return q.Dequeue(); }
    public static double NextDouble() { Confirm(); return double.Parse(q.Dequeue()); }
    public static int[] LineInt() { return Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); }
    public static long[] LineLong() { return Console.ReadLine().Split(' ').Select(long.Parse).ToArray(); }
    public static string[] LineString() { return Console.ReadLine().Split(' ').ToArray(); }
    public static double[] LineDouble() { return Console.ReadLine().Split(' ').Select(double.Parse).ToArray(); }
    public long Abs(long a, long b) => Math.Abs(a - b);
}


Measured memory_bytes: 47032