#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <bitset>
#include <random>
#include <complex>

using namespace std;
typedef long long ll;

const ll segtree_data_init = 0;
const ll segtree_lazy_init = 0;
ll segtree_add_func(ll a, ll b) {// 要素aのbの和
	return a + b;
}
ll segtree_lazy_merge(ll a, ll b) {// 演算子aとbのマージ
	return a + b;
}
ll segtree_lazy_multi(ll a, ll n) {// 演算子aをn個つなげたもの
	return a * n;
}
ll segtree_lazy_divide(ll a) {// 演算子aを二個に分ける
	return a / 2;
}
ll segtree_lazy_apply(ll a, ll x) {// aに演算子xを適用する
	return a + x;
}
class LazySegmentTree {
public:
	LazySegmentTree(vector<ll> v) {
		ll N = (ll)v.size();
		n = 1; while (n < N) n *= 2;
		node.resize(2 * n - 1, segtree_data_init);
		lazy.resize(2 * n - 1, 0);

		for (int i = 0; i < N; i++) node[i + n - 1] = v[i];
		for (int i = n - 2; i >= 0; i--) node[i] = segtree_add_func(node[i * 2 + 1], node[i * 2 + 2]);
	}
	LazySegmentTree(int N, ll init) {
		n = 1; while (n < N) n *= 2;
		node.resize(2 * n - 1);
		lazy.resize(2 * n - 1, segtree_lazy_init);

		for (int i = 0; i < N; i++) node[i + n - 1] = init;
		for (int i = n - 2; i >= 0; i--) node[i] = segtree_add_func(node[i * 2 + 1], node[i * 2 + 2]);
	}


	inline void set(int a, int b, ll x) {
		/*
			[a, b) に演算子xを設定する
		*/
		set(a, b, x, 0, 0, -1);
	}
	inline ll get(int a, int b) {
		/*
			[a, b) の要素の合計を得る
		*/
		return get(a, b, 0, 0, -1);
	}
private:
	void eval(int k, int l, int r) {
		if (lazy[k] != 0) {
			node[k] = segtree_lazy_apply(node[k], lazy[k]);
			if (r - l > 1) {
				lazy[2 * k + 1] = segtree_lazy_merge(lazy[2 * k + 1], segtree_lazy_divide(lazy[k]));
				lazy[2 * k + 2] = segtree_lazy_merge(lazy[2 * k + 2], segtree_lazy_divide(lazy[k]));
			}
			lazy[k] = segtree_lazy_init;
		}
	}
	void set(int a, int b, ll x, int k, int l, int r) {
		if (r < 0) r = n;
		eval(k, l, r);
		if (b <= l || r <= a) return;
		if (a <= l && r <= b) {
			lazy[k] = segtree_lazy_merge(lazy[k], segtree_lazy_multi(x, r - l));
			eval(k, l, r);
		}
		else {
			set(a, b, x, 2 * k + 1, l, (l + r) / 2);
			set(a, b, x, 2 * k + 2, (l + r) / 2, r);
			node[k] = segtree_add_func(node[2 * k + 1], node[2 * k + 2]);
		}
	}
	ll get(int a, int b, int k, int l, int r) {
		if (r < 0) r = n;
		eval(k, l, r);
		if (b <= l || r <= a) return 0;
		if (a <= l && r <= b) return node[k];
		ll vl = get(a, b, 2 * k + 1, l, (l + r) / 2);
		ll vr = get(a, b, 2 * k + 2, (l + r) / 2, r);
		return segtree_add_func(vl, vr);
	}

	int n;
	vector<ll> node, lazy;
};

int main() {
	ll N, D, A; cin >> N >> D >> A;

	vector<pair<ll, ll>> p(N);
	for (int i = 0; i < N; i++) {
		cin >> p[i].first;
		cin >> p[i].second;
	}
	sort(p.begin(), p.end());

	vector<ll> v(N);
	for (int i = 0; i < N; i++) {
		v[i] = (p[i].second + A - 1) / A;
	}

	LazySegmentTree seg(v);

	ll ans = 0;
	int c = 0;
	for (int i = 0; i < N; i++) {
		while (1) {
			if (c == N - 1 || p[c + 1].first > p[i].first + D * 2) {
				break;
			}
			c++;
		}
		ll x = seg.get(i, i + 1);
		if (x > 0) {
			seg.set(i, c + 1, -x);
			ans += x;
		}
	}

	cout << ans << endl;

	return 0;
}

Measured memory_bytes: 14720