#include <bits/stdc++.h>
using namespace std;
 
#define rep(i,j,n) for(int i=j;i<n;++i)
#define all(i) i.begin(),i.end()
#define rall(i) i.rbegin(), i.rend()
#define INF 1e9
#define LINF 1e18
const int mod = 1e9 + 7;
 
typedef long long i64;
typedef pair<int, int> pi;
 
template <class T> using vt = vector<T>;
template <class T> using vvt = vector<vector<T>>;
 
i64 gcd(i64 n, i64 m) {return (m == 0? n : gcd(m, n % m));}
i64 lcm(i64 n, i64 m) {return (n / gcd(n, m) * m);}
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};

template <class Monoid, class OperatorMonoid = Monoid> class LazySegmentTree {
  using F = std::function<Monoid(Monoid, Monoid)>;
  using G = std::function<Monoid(Monoid, OperatorMonoid, int)>;
  using H = std::function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;

  private:
    int n;
    std::vector<Monoid> seg;
    std::vector<OperatorMonoid> lazy;

    const F f;
    const G g;
    const H h;
    const Monoid M1;
    const OperatorMonoid OM1;

    void lazyUpdate(int k, int l, int r) {
      if(lazy[k] == OM1) return;

      if(2 * k + 1 < 2 * n - 1) {
        lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
        lazy[2 * k + 2] = h(lazy[2 * k + 2], lazy[k]);
      }
      seg[k] = g(seg[k], lazy[k], r - l);
      lazy[k] = OM1;
    }

  public:
    LazySegmentTree(int sz, const F f, const G g, const H h, const Monoid &M1, const OperatorMonoid &OM1) : f(f), g(g), h(h), M1(M1), OM1(OM1) {
      n = 1;
      while(n < sz) n *= 2;
      seg.resize(2 * n - 1, M1);
      lazy.resize(2 * n - 1, OM1);
    }

    void update(int a, int b, Monoid x, int k = 0, int l = 0, int r = -1) {
      if(r < 0) r = n;

      lazyUpdate(k, l, r);

      if(b <= l || r <= a) return;

      if(a <= l && r <= b) {
        lazy[k] = h(lazy[k], x);
        lazyUpdate(k, l, r);
      }
      else {
        update(a, b, x, 2 * k + 1, l, (l + r) / 2);
        update(a, b, x, 2 * k + 2, (l + r) / 2, r);
        seg[k] = f(seg[k * 2 + 1], seg[k * 2 + 2]);
      }
    }

    Monoid query(int a, int b, int k = 0, int l = 0, int r = -1) {
      if(r < 0) r = n;

      lazyUpdate(k, l, r);

      if(b <= l || r <= a) return M1;
      if(a <= l && r <= b) return seg[k];
      Monoid vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
      Monoid vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
      return f(vl, vr);
    }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n;
  i64 d, a;
  cin >> n >> d >> a;
  vt<pair<i64, i64>> p(n);
  rep(i, 0, n) {
    i64 x, h;
    cin >> x >> h;
    p[i] = {x, h};
  }
 
  LazySegmentTree<int> seg(n, [](i64 a, i64 b){ return a + b; },
                              [](i64 a, i64 b, i64 len){ return a + b * len; },
                              [](i64 a, i64 b){ return a + b; }, 0, 0);
  sort(all(p));
  vt<i64> x(n), h(n);
  rep(i, 0, n) {
    x[i] = p[i].first;
    seg.update(i, i + 1, p[i].second);
  }
  i64 ans = 0;
  int i = 0;
  while(i < n) {
    int l = i;
    int r = upper_bound(all(x), x[l] + 2 * d) - x.begin();

    i64 h = seg.query(i, i + 1);
    i64 cnt = h / a + !!(h % a);
    i64 damage = cnt * a;
    ans += cnt;
    seg.update(l, r, -damage);
    while(i < n && seg.query(i, i + 1) <= 0) ++i;
  }
  cout << ans << endl;
}

Measured memory_bytes: 10624