#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 2e5+100;

const int maxn = N;
const ll INF = 0x3f3f3f3f3f3f3f3f;
template<class T>
struct Tree {
#define lc (o<<1)
#define rc (lc|1)
#define M (L+(R-L)/2)
    T sumv[maxn*4], minv[maxn*4], maxv[maxn*4], setv[maxn*4], addv[maxn*4];
    int op,y1,y2,n;
    T _sum,_min,_max,v;
    void init(int n) {
        this->n=n;
        build(1,1,n);
        setv[1]=0;
    }
    void build(int o,int L,int R) {
        sumv[o]=minv[o]=maxv[o]=addv[o]=0,setv[o]=-1;
        if(L==R) return;
        build(lc,L,M);
        build(rc,M+1,R);
    }
    void maintain(int o, int L, int R) {
        if(R > L) {
            sumv[o] = sumv[lc] + sumv[rc];
            minv[o] = min(minv[lc], minv[rc]);
            maxv[o] = max(maxv[lc], maxv[rc]);
        }
        if(setv[o] >= 0) { minv[o] = maxv[o] = setv[o]; sumv[o] = setv[o] * (R-L+1); }
        if(addv[o]) { minv[o] += addv[o]; maxv[o] += addv[o]; sumv[o] += addv[o] * (R-L+1); }
    }
    void pushdown(int o) {
        if(setv[o] >= 0) {
            setv[lc] = setv[rc] = setv[o];
            addv[lc] = addv[rc] = 0;
            setv[o] = -1;
        }
        if(addv[o]) {
            addv[lc] += addv[o];
            addv[rc] += addv[o];
            addv[o] = 0;
        }
    }
    void update(int o, int L, int R) {
        if(y1 <= L && y2 >= R) {
            if(op == 1) addv[o] += v;
            else { setv[o] = v; addv[o] = 0; }
        } else {
            pushdown(o);
            if(y1 <= M) update(lc, L, M); else maintain(lc, L, M);
            if(y2 > M) update(rc, M+1, R); else maintain(rc, M+1, R);
        }
        maintain(o, L, R);
    }
    void query(int o, int L, int R, T add) {
        if(setv[o] >= 0) {
            T v = setv[o] + add + addv[o];
            _sum += v * (min(R,y2)-max(L,y1)+1);
            _min = min(_min, v);
            _max = max(_max, v);
        } else if(y1 <= L && y2 >= R) {
            _sum += sumv[o] + add * (R-L+1);
            _min = min(_min, minv[o] + add);
            _max = max(_max, maxv[o] + add);
        } else {
            if(y1 <= M) query(o*2, L, M, add + addv[o]);
            if(y2 > M) query(o*2+1, M+1, R, add + addv[o]);
        }
    }
    void A(int L,int R,T v) {
        y1=L,y2=R,op=1,this->v=v;
        update(1,1,n);
    }
    void S(int L,int R,T v) {
        y1=L,y2=R,op=2,this->v=v;
        update(1,1,n);
    }
    void Q(int L,int R) {
        _sum=0,_min=INF,_max=-INF;
        y1=L,y2=R;
        query(1,1,n,0);
    }
#undef lc
#undef rc
#undef M
};

Tree<ll> t;

ll n,d,a;
pair<ll,ll> p[N];
ll b[N],m;

int main() {
    ios::sync_with_stdio(0);
    cin>>n>>d>>a;
    t.init(n);
    for(int i=0;i<n;i++) {
        cin>>p[i].first>>p[i].second;
        b[i] = p[i].first;
    }
    sort(p,p+n);
    sort(b,b+n);
    for(int i=0;i<n;i++) {
        int x = lower_bound(b,b+n,p[i].first) - b + 1;
        t.S(x,x,p[i].second);
    }
    ll ans = 0;
    
    for(int i=1;i<=n;i++) {
        t.Q(i,i);
        ll now = t._sum;
        if(now<0) continue;
        ll need = (t._sum + a - 1)/a;
        ans += need;
        ll R = b[i-1] + 2*d; 
        int j = upper_bound(b,b+n,R) - b;
        j = min(j,(int)n);
        t.A(i,j,-a*need);
    }
    cout<<ans<<endl;
    return 0;
}




Measured memory_bytes: 35072