#include<functional>
#include<iostream>
#include<memory>
template<typename S, typename E = S> class SegmentTreeDLP {
 public:
  using Size = long long;
  using FS = std::function<S(S, S)>;
  using FA = std::function<S(S, E)>;
  using FE = std::function<E(E, E)>;
  SegmentTreeDLP(Size n, FS fs, FA fa, FE fe, S es, E ee) : n(n), fs(fs), fa(fa), fe(fe), es(es), ee(ee), root(std::make_unique<Node>(es,ee)) {}
  void update(Size a, Size b, E x) {update(a, b, x, root, 0, n);}
  S query(Size a, Size b) {return query(a, b, root, 0, n);}
  Size lower_bound(Size a, Size b, const std::function<bool(S)>& check) {return lower_bound(a, b, check, root, 0, n);}
  void debug() {std::cout << "segtree: size " << n << std::endl; traverse(root, 0, 0, n);}
  void traverse(const auto& node, Size d, Size l, Size r) {
    if(not node->lchild || not node->rchild) return;
    propagate(node);
    auto m = (l + r) / 2;
    if(l+1!=r) traverse(node->rchild, d + 1, m, r);
    for(auto i = 0; i < d; ++i) std::cout << "  ";
    std::cout << "[" << l << "," << r << ") ";
    std::cout << node->val << std::endl;
    if(l+1!=r) traverse(node->lchild, d + 1, l, m);
  }
 private:
  struct Node {
    S val;
    E laz;
    std::unique_ptr<Node> lchild, rchild;
    Node(S val, E laz) : val(val), laz(laz) {}
  };
  inline S reflect(const auto& n) {return fa(n->val, n->laz);}
  inline void propagate(const auto& n) {
    if(not n->lchild) n->lchild = std::make_unique<Node>(es, ee);
    if(not n->rchild) n->rchild = std::make_unique<Node>(es, ee);
    if(n->laz == ee) return;
    n->lchild->laz = fe(n->lchild->laz, n->laz);
    n->rchild->laz = fe(n->rchild->laz, n->laz);
    n->val = reflect(n);
    n->laz = ee;
  }
  void update(Size a, Size b, E x, const auto &n, Size l, Size r) {
    propagate(n);
    if(b <= l || r <= a) return;
    if(a <= l && r <= b) {
      n->laz = fe(n->laz, x);
      propagate(n);
      return;
    }
    auto m = (l + r) / 2;
    update(a, b, x, n->lchild, l, m);
    update(a, b, x, n->rchild, m, r);
    n->val = fs(n->lchild->val, n->rchild->val);
  }
  S query(Size a, Size b, const auto &n, Size l, Size r) {
    propagate(n);
    if(b <= l || r <= a) return es;
    if(a <= l && r <= b) return reflect(n);
    auto m = (l + r) / 2;
    auto vl = query(a, b, n->lchild, l, m);
    auto vr = query(a, b, n->rchild, m, r);
    return fs(vl, vr);
  }
  Size lower_bound(Size a, Size b, const auto& check, const auto& node, Size l, Size r) {
    propagate(node);
    if(b <= l || r <= a) return n;
    if(!check(reflect(node))) return n;
    if(l + 1 == r) return l;
    auto m = (l + r) / 2;
    auto i = lower_bound(a, b, check, node->lchild, l, m);
    if(i != n) return i;
    return lower_bound(a, b, check, node->rchild, m, r);
  }
  Size n;
  std::unique_ptr<Node> root;
  FS fs;
  FA fa;
  FE fe;
  S es;
  E ee;
};

#include<bits/stdc++.h>
using namespace std;

using LL = long long;

struct S {
  LL v, size;
  bool operator==(const S& o) const {return v != o.v;}
  friend ostream& operator<<(ostream& os, const S& s) {return os << s.v;}
};
using E = LL;
auto fs = [&](S l, S r) {return S{l.v + r.v, l.size + r.size};};
auto fa = [&](S l, E r) {return S{l.v + r * l.size, l.size};};
auto fe = [&](E l, E r) {return l + r;};
auto es = S{0, 1};
auto ee = 0;

int main() {
  LL N, D, A;
  cin >> N >> D >> A;
  struct Monster {LL x, h;};
  vector<Monster> monster(N);
  for(auto& m: monster) cin >> m.x >> m.h;

  sort(begin(monster), end(monster), [](auto l, auto r) {return l.x < r.x;});

  SegmentTreeDLP<S, E> bomb(3e9+1, fs, fa, fe, es, ee);
  for(auto m: monster) bomb.update(m.x, m.x+1, m.h);

  LL ans = 0;
  for(auto m: monster) {
    auto h = bomb.query(m.x, m.x+1).v;
    if(h <= 0) continue;
    auto n = (h+A-1)/A;
    ans += n;
    bomb.update(m.x, m.x + 2*D + 1, -n*A);
//     cout<<"place: "<<m.x+D<<", number: "<<n<<endl;
  }
  cout << ans << endl;
}


Measured memory_bytes: 733696