#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#ifdef ENABLE_DEBUG
#define dump(a) cerr<<#a<<"="<<a<<endl
#define dumparr(a,n) cerr<<#a<<"["<<n<<"]="<<a[n]<<endl
#else
#define dump(a) 
#define dumparr(a,n) 
#endif
#define FOR(i, a, b) for(ll i = a;i < b;i++)
#define For(i, a) FOR(i, 0, a)
#define REV(i, a, b) for(ll i = b-1;i >= a;i--)
#define Rev(i, a) REV(i, 0, a)
#define REP(a) For(i, a)
#define SIGN(a) (a==0?0:(a>0?1:-1))

typedef long long int ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<ll, ll> pll;
typedef pair<ll,pll> ppll;
typedef vector<ll> vll;
typedef long double ld;
typedef pair<ld,ld> pdd;

const ll INF=(1LL<<50);
#if __cplusplus<201700L
ll gcd(ll a, ll b) {
  if(a < b) return gcd(b, a);
  ll r;
  while ((r=a%b)) {
    a = b;
    b = r;
  }
  return b;
}
#endif

template<class S,class T>
std::ostream& operator<<(std::ostream& os,pair<S,T> a){
  os << "(" << a.first << "," << a.second << ")";
  return os;
}
template<class T>
std::ostream& operator<<(std::ostream& os,vector<T> a){
  os << "[ ";
  REP(a.size()){
    os<< a[i] << " ";
  }
  os<< " ]";
  return os;
}
 template<typename T>
 struct LazySegmentTree {
 
 private:
     ll n;
     T init_v;
     vector<T> node;
     vector<T> lazy;
 
 public:
     LazySegmentTree(vector<T> a, T _init_v) {
 
         n = 1;
         init_v = _init_v;
 
         ll sz = a.size();
         while (n < sz) n *= 2;
 
         node.resize(2 * n, init_v);
         lazy.resize(2 * n, init_v);
 
         for (ll i = 0; i < sz; i++) node[i + n - 1] = a[i];
         for (ll i = n - 2; i >= 0; i--) node[i] = node[i * 2 + 1] + node[i * 2 + 2];
     }
 
     void eval(ll k, ll l, ll r) {
         if (lazy[k] != 0) {
             node[k] += lazy[k];
             if (r - l > 1) {
                 lazy[k * 2 + 1] += lazy[k] / 2;
                 lazy[k * 2 + 2] += lazy[k] / 2;
             }
             lazy[k] = 0;
         }
     }
 
     void add(ll a, ll b, T x, ll k = 0, ll l = 0, ll r = -1) {
         if (r < 0) r = n;
         eval(k, l, r);
         if (r <= a || b <= l) return;
         if (a <= l && r <= b) {
             lazy[k] += (r - l) * x;
             eval(k, l, r);
         } else {
             add(a, b, x, k * 2 + 1, l, (l + r) / 2);
             add(a, b, x, k * 2 + 2, (l + r) / 2, r);
             node[k] = node[k * 2 + 1] + node[k * 2 + 2];
         }
     }
 
     T getsum(ll a, ll b, ll k = 0, ll l = 0, ll r = -1) {
         if (r < 0) r = n;
         eval(k, l, r);
         if (r <= a || b <= l) return 0;
         if (a <= l && r <= b) return node[k];
         T lv = getsum(a, b, k * 2 + 1, l, (l + r) / 2);
         T rv = getsum(a, b, k * 2 + 2, (l + r) / 2, r);
         return lv + rv;
     }
 
 };

void solve(long long N, long long D, long long A, std::vector<long long> X, std::vector<long long> H){
  map<ll,ll> za;
  vector<pll> enemy(N);
  REP(N){
    enemy[i]=pll(X[i],H[i]);
  }
  sort(enemy.begin(),enemy.end());
  REP(N){
    za[enemy[i].first]=i;
  }
  vector<ll> enh(N);
  REP(N){
    enh[i]=enemy[i].second;
  }
  auto tree = LazySegmentTree<ll>(enh,0LL);
  ll ans=0;
  REP(N){
    ll r=prev(za.upper_bound(enemy[i].first+D*2))->second;
    ll h=tree.getsum(i,i+1);
    dump(r);
    dump(h);
    if(h<=0)continue;
    ll num=(h/A+(h%A>0?1:0));
    ans+=num;
    tree.add(i,r+1,-(num*A));
  }
  cout<<ans<<endl;
}

int main(){
  cout<<setprecision(1000);
  cin.tie(0);
  ios::sync_with_stdio(false);
    long long N;
    scanf("%lld",&N);
    long long D;
    scanf("%lld",&D);
    long long A;
    scanf("%lld",&A);
    std::vector<long long> X(N);
    std::vector<long long> H(N);
    for(int i = 0 ; i < N ; i++){
        scanf("%lld",&X[i]);
        scanf("%lld",&H[i]);
    }
    solve(N, D, A, std::move(X), std::move(H));
    return 0;
}


Measured memory_bytes: 30336