#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <functional>
#include <bitset>
#include <cassert>
#include <random>
using namespace std;
using ll = long long;


class LazySegmentTree {
	// TODO: Change Monid and Operator, their identity, their product, and the action.
	using Monoid = ll;
	const Monoid INI_MONOID = 0;
	Monoid monoid_product(const Monoid &a, const Monoid &b) {
		return a + b;
	}

	using Operator = ll;
	const Operator INI_OPERATOR = 0;
	// p(q(a)) (i.e., not q(p(a)))
	Operator operator_product(const Operator &p, const Operator &q) {
		return p + q;
	}

	// a |-> b = (p, n)(a)
	// n: Length of the range.
	Monoid act(const Operator &p, int n, const Monoid &a) {
		return p*n + a;
	}


	int num;
	vector<Monoid> dat_mono;
	vector<Operator> dat_op;

public:
	LazySegmentTree(int n) {
		num = 1;
		while (num < n) num *= 2;
		dat_mono = vector<Monoid>(2 * num, INI_MONOID);
		dat_op = vector<Operator>(2 * num, INI_OPERATOR);
	}

	LazySegmentTree(const vector<Monoid> &m) : LazySegmentTree(m.size()) {
		int n = m.size();
		for (int i = 0; i < n; i++) {
			dat_mono[num - 1 + i] = m[i];
		}
		for (int i = num - 2; i >= 0; i--) {
			dat_mono[i] = monoid_product(dat_mono[2 * i + 1], dat_mono[2 * i + 2]);
		}
	}

	// Apply the operator q to the range [a, b).
	// k: The index of the node.
	// Call like apply(q, a, b)
	void apply(Operator q, int a, int b, int k = 0, int left = 0, int right = -1) {
		if (right < 0) right = num;
		if (right <= a || b <= left) return;
		if (a <= left && right <= b) {
			dat_mono[k] = act(q, right - left, dat_mono[k]);
			dat_op[k] = operator_product(q, dat_op[k]);
			return;
		}
		apply(dat_op[k], left, left + (right - left) / 2, 2 * k + 1, left, left + (right - left) / 2); // Left side
		apply(dat_op[k], left + (right - left) / 2, right, 2 * k + 2, left + (right - left) / 2, right); // Right side
		dat_op[k] = INI_OPERATOR;
		apply(q, a, b, 2 * k + 1, left, left + (right - left) / 2); // Left side
		apply(q, a, b, 2 * k + 2, left + (right - left) / 2, right); // Right side
		dat_mono[k] = monoid_product(dat_mono[2 * k + 1], dat_mono[2 * k + 2]);
	}

	// Get the value of the range [a, b).
	// k: The index of the node.
	// [left, right): The range corresponds to the k-th node.
	// Call like getval(a, b).
	Monoid getval(int a, int b, int k = 0, int left = 0, int right = -1) {
		if (right < 0) right = num;
		if (right <= a || b <= left) return INI_MONOID;
		if (a <= left && right <= b) return dat_mono[k];
		Monoid vleft = getval(a, b, 2 * k + 1, left, left + (right - left) / 2); // Left side
		Monoid vright = getval(a, b, 2 * k + 2, left + (right - left) / 2, right); // Right side
		return act(dat_op[k], max(0, min(b, right) - max(a, left)), monoid_product(vleft, vright));
	}
};

int main() {
	ll n, d, a; cin >> n >> d >> a;
	vector<pair<int, int>> xh(n);
	for (int i = 0; i < n; i++) {
		cin >> xh[i].first >> xh[i].second;
	}
	sort(xh.begin(), xh.end());
	vector<ll> x(n), h(n);
	for (int i = 0; i < n; i++) {
		x[i] = xh[i].first;
		h[i] = xh[i].second;
	}
	LazySegmentTree seg(h);
	ll ans = 0;
	for (int i = 0; i < n; i++) {
		ll hp = seg.getval(i, i + 1);
		if (hp <= 0) continue;

		ll r = x[i] + 2 * d;
		int right = upper_bound(x.begin(), x.end(), r) - x.begin();
		ll t = (hp + a - 1) / a;
		ans += t;
		seg.apply(-t*a, i, right);
	}
	cout << ans << endl;
	return 0;
}


Measured memory_bytes: 13184