/*
    Author:zeke
    
    pass System Test!
    GET AC!!
*/
#include <iostream>
#include <queue>
#include <vector>
#include <iostream>
#include <vector>
#include <string>
#include <cassert>
#include <algorithm>
#include <functional>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <map>
#include <iomanip>
#include <utility>
#include <stack>
#include <bitset>
using ll = long long;
using ld = long double;
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(), (x).end()
#define rep3(var, min, max) for (ll(var) = (min); (var) < (max); ++(var))
#define repi3(var, min, max) for (ll(var) = (max)-1; (var) + 1 > (min); --(var))
#define Mp(a, b) make_pair((a), (b))
#define F first
#define S second
#define Icin(s) \
    ll(s);      \
    cin >> (s);
#define Scin(s) \
    ll(s);      \
    cin >> (s);
template <class T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T &a, const T &b)
{
    if (b < a)
    {
        a = b;
        return 1;
    }
    return 0;
}
typedef pair<ll, ll> P;
typedef vector<ll> V;
typedef vector<V> VV;
typedef vector<P> VP;
ll mod = 1e9 + 7;
ll MOD = 1e9 + 7;
ll INF = 1e18;
const int sqrtN = 512;
struct SqrtDecomposition
{
    int N, K;
    vector<int> data;
    vector<int> bucketAdd;
    SqrtDecomposition(int n) : N(n)
    {
        K = (N + sqrtN - 1) / sqrtN;
        data.assign(K * sqrtN, 0);
        bucketAdd.assign(K, 0);
    }
    // [s, t)
    void add(int s, int t, int x)
    {
        for (int k = 0; k < K; ++k)
        {
            int l = k * sqrtN, r = (k + 1) * sqrtN;
            if (r <= s || t <= l)
                continue;
            if (s <= l && r <= t)
            {
                bucketAdd[k] += x;
            }
            else
            {
                for (int i = max(s, l); i < min(t, r); ++i)
                {
                    data[i] += x;
                }
            }
        }
    }
    int get(int i)
    {
        int k = i / sqrtN;
        return data[i] + bucketAdd[k];
    }
};
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll n, d, a;
    cin >> n >> d >> a;
    VP vec(n);
    map<ll, ll> mp;
    V temp(n);
    V reg(n);
    rep(i, n)
    {
        cin >> vec[i].F >> vec[i].S;
        if (vec[i].S % a == 0)
        {
            vec[i].S = vec[i].S / a;
        }
        else
        {
            vec[i].S = vec[i].S / a + 1;
        }
        mp[vec[i].F] = vec[i].S;
        temp[i] = vec[i].F;
        reg[i] = vec[i].S;
    }
    //cout<<"helo"<<endl;
    
    sort(all(vec));
    sort(all(temp));
    rep(i,n){
        reg[i]=mp[vec[i].F];
    }
    SqrtDecomposition tree(n+100);
    ll sum = 0;
    rep(i, n)
    {
       // cout<<"hello"<<endl;
        if (tree.get(i) >= reg[i])
        {
            continue;
        }
      //  cout<<tree.get(i)<<" "<<reg[i]<<endl;
        ll sumtemp = tree.get(i);
        ll k = lower_bound(all(temp), vec[i].F + 2 * d) - temp.begin();
      //  cout<<i<<"から"<<" "<< k <<"まで "<<reg[i]-sumtemp<<" 足す"<<"、現実幅　"<<vec[i].F<<" "<<vec[i].F + 2 * d<<"間可能"<<endl;
        tree.add(i, k , reg[i]-sumtemp);
        sum += reg[i]-sumtemp;
    }
    SqrtDecomposition tree2(n+100);
    ll sum2 = 0;
    for(int i=n-1;i>=0;i--)
    {
       // cout<<"hello"<<endl;
        if (tree2.get(i) >= reg[i])
        {
            continue;
        }
     //   cout<<i<<" "<<tree2.get(i)<<" "<<reg[i]<<endl;
        ll sumtemp = tree2.get(i);
        ll k = lower_bound(all(temp), vec[i].F - 2 * d) - temp.begin();
      //  cout<<k<<"から"<<" "<< i <<"まで "<<reg[i]-sumtemp<<" 足す"<<"、現実幅　"<<vec[i].F<<" "<<vec[i].F - 2 * d<<"間可能"<<endl;
        tree2.add(k, i , reg[i]-sumtemp);
        sum2 += reg[i]-sumtemp;
    }
    cout << min(sum,sum2) << endl;
}


Measured memory_bytes: 20608