#include <bits/stdc++.h>
#include <functional>
using namespace std;

typedef long long int ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<string>vst;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef map<int,int> dct;

#define fastio ios_base::sync_with_stdio(false);cin.tie(0)
#define all(ct) ct.begin() , ct.end()
#define endl "\n"
#define fr(i,a) for(auto i:a)
#define f(i,a,b) for(int i=a;i<b;++i)
#define fd(i,a,b) for(int i=a;i>=b;--i)
#define pb push_back
#define in(d,v) d.find(v)!=d.end()
#define mp make_pair
#define size(a) int(a.size())

const ll mod = 1e9 + 7;
const ll inf = ll(1e18);
const double PI = acos(-1);

ll modexp(ll x,ll n,ll md){
    if(n==0)return 1;
    if(n%2==0)return modexp((x*x)%md,n/2,md);
    return (x*modexp((x*x)%md,n/2,md))%md;
}

bool compare(pll a,pll b){
    return a.first*b.second>a.second*b.first;
}

struct Node{
    ll val,lazy;
}tree[800000];

vl a;

void build(int node, int start, int end){
    tree[node].lazy=0;
    if(start == end){
        tree[node].val = a[start];
        return;
    }
    int mid = (start + end) / 2;
    build(2*node+1, start, mid);
    build(2*node+2, mid+1, end);
    tree[node].val = tree[2*node+1].val + tree[2*node+2].val;
}

void updateRange(int node, int start, int end, int l, int r, ll x){
    if(tree[node].lazy!=0){
        tree[node].val += (end - start + 1) * tree[node].lazy;
        if(start != end){
            tree[node*2+1].lazy += tree[node].lazy;
            tree[node*2+2].lazy += tree[node].lazy;
        }
        tree[node].lazy = 0;
    }
    if(start > end or start > r or end < l)return;
    if(start >= l and end <= r){
        tree[node].val += (end - start + 1) * x;
        if(start != end){
            tree[node*2+1].lazy += x;
            tree[node*2+2].lazy += x;
        }
        return;
    }
    int mid = (start + end) / 2;
    updateRange(node*2+1, start, mid, l, r, x);
    updateRange(node*2 + 2, mid + 1, end, l, r, x);
    tree[node].val = tree[node*2+1].val + tree[node*2+2].val;
}

int queryRange(int node, int start, int end, int l, int r){
    if(start > end or start > r or end < l)return 0;
    if(tree[node].lazy != 0){
        tree[node].val += (end - start + 1) * tree[node].lazy;
        if(start != end){
            tree[node*2+1].lazy += tree[node].lazy;
            tree[node*2+2].lazy += tree[node].lazy;
        }
        tree[node].lazy = 0;
    }
    if(start >= l and end <= r)return tree[node].val;
    int mid = (start + end) / 2;
    int p1 = queryRange(node*2+1, start, mid, l, r);
    int p2 = queryRange(node*2 + 2, mid + 1, end, l, r);
    return (p1 + p2);
}
int main(){
    fastio;
    //clock_t tm = clock();
    ll n,d,z,x,h;
    cin>>n>>d>>z;
    vi p;vii c;
    f(i,0,n){
        cin>>x>>h;
        c.pb({x,h});
    }
    sort(all(c));
    f(i,0,n){
        p.pb(c[i].first);a.pb(ll(c[i].second));
    }
    ll ans=0,temp;
    build(0,0,n-1);
    f(i,0,n){
        x=queryRange(0,0,n-1,i,i);
        if(x<=0)
            continue;
        temp=ceil((x*1.0)/z);
        ans+=temp;
        int r=upper_bound(all(p),p[i]+2*d)-p.begin();
        --r;
        updateRange(0,0,n-1,i,r,-temp*z);
    }
    cout<<ans<<endl;
    //cout<<((clock()-tm)*1.0)/CLOCKS_PER_SEC<<endl;
}

Measured memory_bytes: 17240