//Dragon_warrior7(IITK)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define nl cout << '\n'
#define sor(x) sort(x.begin(), x.end())
#define rev(v) reverse(v.begin(), v.end())
#define lb(v, temp) lower_bound(v.begin(), v.end(), temp)
#define ub(v, temp) upper_bound(v.begin(), v.end(), temp)
#define fi first
#define se second
#define llmax 1000000000000000000
#define deb(x) cout << #x << " " << x << "\n"
#define pll pair<ll, ll> 
#define vll vector<ll> 
#define rub cout << "\n------------------------------------\n"
void read(vector<ll> &v)
{
	for (int i = 0; i < v.size(); i++)
		cin >> v[i];
}

void print(vector<ll> v)
{
	for (int i = 0; i < v.size(); i++)
		cout << v[i] << " ";
}
ll n,m,a,b,temp,x,y;
string str;
set<ll> s;
ll tree[8*100000]={0};
ll lazy[8*100000]={0};
void build(ll a[], int v, int tl, int tr) {
    if (tl == tr) {
        tree[v] = a[tl];
    } else {
        int tm = (tl + tr) / 2;
        build(a, v*2, tl, tm);
        build(a, v*2+1, tm+1, tr);
        tree[v] = tree[v*2] + tree[v*2+1];
    }
}
void updateRange(int node, int start, int end, int l, int r, ll val)
{
    if(lazy[node] != 0)
    { 
        tree[node] += (end - start + 1) * lazy[node]; 
        if(start != end)
        {
            lazy[node*2] += lazy[node];         
            lazy[node*2+1] += lazy[node];       
        }
        lazy[node] = 0;                             
    }
    if(start > end or start > r or end < l)              // Current segment is not within range [l, r]
        return;
    if(start >= l and end <= r)
    {
        // Segment is fully within range
        tree[node] += (end - start + 1) * val;
        if(start != end)
        {
            // Not leaf node
            lazy[node*2] += val;
            lazy[node*2+1] += val;
        }
        return;
    }
    int mid = (start + end) / 2;
    updateRange(node*2, start, mid, l, r, val);        // Updating left child
    updateRange(node*2 + 1, mid + 1, end, l, r, val);   // Updating right child
    tree[node] = tree[node*2] + tree[node*2+1];        // Updating root with max value 
}

ll queryRange(int node, int start, int end, int l, int r)
{
    if(start > end or start > r or end < l)
        return 0;         // Out of range
    if(lazy[node] != 0)
    {
        // This node needs to be updated
        tree[node] += (end - start + 1) * lazy[node];            // Update it
        if(start != end)
        {
            lazy[node*2] += lazy[node];         // Mark child as lazy
            lazy[node*2+1] += lazy[node];    // Mark child as lazy
        }
        lazy[node] = 0;                 // Reset it
    }
    if(start >= l and end <= r)             // Current segment is totally within range [l, r]
        return tree[node];
    int mid = (start + end) / 2;
    ll p1 = queryRange(node*2, start, mid, l, r);         // Query left child
    ll p2 = queryRange(node*2 + 1, mid + 1, end, l, r); // Query right child
    return (p1 + p2);
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin>>n;
    cin>>b;
    cin>>a;
    vector<pll> vp(n);
    for(int i=0;i<n;i++)
    {
        cin>>vp[i].fi>>vp[i].se;
    }
    sor(vp);
    ll health[n];
    for(int i=0;i<n;i++)
    {
        health[i]=vp[i].se;
    }
    build(health,1,0,n-1);
    ll ans=0;
    //cout<<queryRange(1,0,n-1,0,1);
    //nl;
    for(int i=n-1;i>=0;i--)
    {
       if(queryRange(1,0,n-1,i,i)<=0)
       continue;
       temp=(queryRange(1,0,n-1,i,i)+(a-1))/a;
       ans+=temp;
       pll p1={vp[i].fi-2*b,0};
       int index1=lb(vp,p1)-vp.begin();
       updateRange(1,0,n-1,index1,i,-a*temp);
    }
    cout<<ans;
}

Measured memory_bytes: 17280