#include <bits/stdc++.h>

using namespace std;

/* g++ -g -fsanitize=address -lasan -std=c++11 -Dfoo_ */

/* freopen("input.txt", "rt", stdin); */
/* freopen("output.txt", "wt", stdout); */

#define ALL(c)          (c).begin(), (c).end()
#define ALLR(c)         (c).rbegin(), (c).rend()
#define FOR(i,a,b)      for (int i=(a); i < (b); ++i)
#define FORR(i,a,b)     for (int i=(a); i > (b); --i)
#define FOR_ALL(i,c)    for (__typeof((c).begin()) i=(c).begin();   \
                             i != (c).end(); ++i)
#define FOR_ALLR(i,c)   for (__typeof((c).rbegin()) i=(c).rbegin(); \
                             i != (c).rend(); ++i)
#define SZ(array)       (sizeof(array)/sizeof(array[0]))
#define lc(x)           (x<<1)     /* 2*x */
#define rc(x)           (x<<1 | 1) /* 2*x+1 */
#define lowbit(x)       (x & (-x)) /* 0b10100 -> 0b100 */

typedef long long       LL;
typedef map<int,int>    MII;
typedef pair<int,int>   PII;
typedef set<int>        SI;
typedef vector<bool>    VB;
typedef vector<double>  VD;
typedef vector<int>     VI;
typedef vector<string>  VS;

/* check if a key is in container C */
template <class C>
inline bool in_(const typename C::key_type& k, const C& A)
{ return A.find(k) != A.end(); }
inline bool in_(const string& s, const string& S)
{ return S.find(s) != string::npos; }

const int maxn = 2e5+5;
struct node { int lft,rht; } tree[maxn*4];
LL add[maxn*4], sum[maxn*4];

int mid(const int r)
{ return (tree[r].lft + tree[r].rht) / 2; }
int siz(const int r)
{ return tree[r].rht - tree[r].lft; }

void pushup(const int r)
{ sum[r] = sum[lc(r)] + sum[rc(r)]; }

void pushdown(const int r)
{
    add[lc(r)] += add[r];
    add[rc(r)] += add[r];
    sum[lc(r)] += add[r] * siz(lc(r));
    sum[rc(r)] += add[r] * siz(rc(r));
    add[r] = 0;
}

void update(const int lft, const int rht, const LL v, const int r)
{
    if (rht-lft < 1)
        return;
    /* r == [lft,rht) range */
    if (tree[r].lft == lft && rht == tree[r].rht) {
        add[r] += v;
        sum[r] += v * siz(r);
        return;
    }
    /* r is bigger than [lft,rht), need to move down */
    pushdown(r);
    if (rht < mid(r))
        update(lft, rht, v, lc(r));
    else if (lft >= mid(r))
        update(lft, rht, v, rc(r));
    else {
        update(lft, mid(r), v, lc(r));
        update(mid(r), rht, v, rc(r));
    }
    pushup(r);
}

LL query(const int lft, const int rht, const int r)
{
    if (rht-lft < 1)
        return 0;
    if (tree[r].lft == lft && rht == tree[r].rht)
        return sum[r];
    pushdown(r);
    LL ans = 0;
    if (rht < mid(r))
        ans += query(lft, rht, lc(r));
    else if (lft >= mid(r))
        ans += query(lft, rht, rc(r));
    else {
        ans += query(lft, mid(r), lc(r));
        ans += query(mid(r), rht, rc(r));
    }
    return ans;
}

void build(const int lft, int rht, const int r)
{
    assert(rht-lft >= 1);
    tree[r].lft = lft;
    tree[r].rht = rht;
    if (rht-lft > 1) {
        build(lft, mid(r), lc(r));
        build(mid(r), rht, rc(r));
        pushup(r);
    }
}

int main()
{
#ifdef foo_
    freopen("foo", "rt", stdin);
#endif
    ios::sync_with_stdio(false);
    int n,d,a;
    while (cin >> n >> d >> a) {
        memset(add,0,sizeof(add));
        memset(sum,0,sizeof(sum));
        vector<PII> A(n);
        FOR(i,0,n)
            cin >> A[i].first >> A[i].second;
        sort(ALL(A));
        vector<LL> x(n), h(n);
        FOR(i,0,n)
            x[i] = A[i].first, h[i] = A[i].second;
        int sz = 1;
        while (sz < n)
            sz *= 2;
        build(0,sz,1);
        LL ans = 0;
        FOR(i,0,n) {
            h[i] -= query(i,i+1,1) * a;
            if (h[i] > 0) {
                const int j = upper_bound(ALL(x), x[i]+2*d) - x.begin();
                const int c = (h[i]+a-1) / a;
                update(i,j,c,1);
                ans += c;
            }
        }
        cout << ans << endl;
    }
    return 0;
}


Measured memory_bytes: 23424