#include <bits/stdc++.h>
#define int long long
#define x first
#define y second
#define hashset unordered_set
#define hashmap unordered_map
#define getbit(x, i) (((x) >> (i)) & 1)
using namespace std;
typedef pair<int, int> pii;
template <typename T>
inline vector<T> readvector(size_t size) {
    vector<T> res(size);
    for (size_t i = 0; i < size; ++i) {
        cin >> res[i];
    }
    return res;
}
template <typename T>
inline void printvector(vector<T> &arr, string sep = " ", string ends = "\n") {
    for (size_t i = 0; i < arr.size(); ++i) {
    }
}
inline int binPow(int x, int deg, int mod) {
    int ans = 1;
    for (int i = sizeof(x) * CHAR_BIT - 1; i >= 0; i--) {
        ans *= ans;
        ans %= mod;
        if (getbit(deg, i)) ans *= x;
        ans %= mod;
    }
    return ans;
}
const int MAXN = 2e5 + 10;
const int MOD = 1e9 + 7;

int mod[MAXN * 4];
int tree[MAXN * 4];
int x[MAXN], h[MAXN];

void build(int v, int l, int r) {
    if (l + 1 == r) {
        tree[v] = h[l];
    } else {
        int m = (l + r) / 2;
        build(v * 2 + 0, l, m);
        build(v * 2 + 1, m, r);
        tree[v] = max(tree[v * 2], tree[v * 2 + 1]);
    }
    mod[v] = 0;
}

inline void push(int v) {
    mod[v * 2] += mod[v];
    mod[v * 2 + 1] += mod[v];
    mod[v] = 0;
}

inline int get_val(int v) {
    return tree[v] + mod[v];
}

int down(int v, int l, int r) {
    if (l + 1 == r) return l;
    push(v);
    int ans = 0;
    if (get_val(v * 2) > 0) {
        ans = down(v * 2, l, (l + r) / 2);
    } else {
        ans = down(v * 2 + 1, (l + r) / 2, r);
    }
    tree[v] = max(get_val(v * 2), get_val(v * 2 + 1));
    return ans;
}

int get(int v, int l, int r, int pos) {
    if (l + 1 == r) return get_val(v);
    int m = (l + r) / 2;
    if (pos < m)
        return mod[v] + get(v * 2, l, m, pos);
    else
        return mod[v] + get(v * 2 + 1, m, r, pos);
}

void upd(int v, int tl, int tr, int l, int r, int val) {
    if (tr <= l || r <= tl) return;
    if (l <= tl && tr <= r) {
        mod[v] += val;
        return;
    }
    int tm = (tl + tr) / 2;
    push(v);
    upd(v * 2, tl, tm, l, r, val);
    upd(v * 2 + 1, tm, tr, l, r, val);
    tree[v] = max(get_val(v * 2), get_val(v * 2 + 1));
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int n, d, a;
    cin >> n >> d >> a;
    vector<int> xs;
    for (int i = 0; i < n; i++) {
        cin >> x[i] >> h[i];
        xs.push_back(x[i]);
    }
    sort(xs.begin(), xs.end());
    xs.resize(unique(xs.begin(), xs.end()) - xs.begin());
    for (int i = 0; i < n; i++) {
        x[i] = lower_bound(xs.begin(), xs.end(), x[i]) - xs.begin();
    }
    vector<pii> tmp;
    for (int i = 0; i < n; i++) {
        tmp.push_back({x[i], h[i]});
    }
    sort(tmp.begin(), tmp.end());
    for (int i = 0; i < n; i++) {
        x[i] = tmp[i].x;
        h[i] = tmp[i].y;
    }

    build(1, 0, n);
    int ans = 0;

    while (1) {
        int pos = down(1, 0, n);
        int val = get(1, 0, n, pos);
        if (val <= 0) break;
        int right =
            upper_bound(xs.begin(), xs.end(), xs[pos] + 2 * d) - xs.begin();
        int minus = (val + a - 1) / a * a;
        upd(1, 0, n, pos, right, -minus);
        ans += minus / a;
    }
    cout << ans << endl;

    return 0;
}

Measured memory_bytes: 19564