Problem:
Score : 600 points

Problem Statement

Silver Fox is fighting with N monsters.

The monsters are standing in a row, and we can assume them to be standing on a number line. The i-th monster, standing at the coordinate X_i, has the health of H_i.

Silver Fox can use bombs to attack the monsters.
Using a bomb at the coordinate x decreases the healths of all monsters between the coordinates x-D and x+D (inclusive) by A.
There is no way other than bombs to decrease the monster's health.

Silver Fox wins when all the monsters' healths become 0 or below.

Find the minimum number of bombs needed to win.

Constraints

1 \leq N \leq 2 \times 10^5

0 \leq D \leq 10^9

1 \leq A \leq 10^9

0 \leq X_i \leq 10^9

1 \leq H_i \leq 10^9

X_i are distinct.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N D A
X_1 H_1
:
X_N H_N

Output

Print the minimum number of bombs needed to win.

Sample Input 1

3 3 2
1 2
5 4
9 2

Sample Output 1

2

First, let us use a bomb at the coordinate 4 to decrease the first and second monsters' health by 2.

Then, use a bomb at the coordinate 6 to decrease the second and third monsters' health by 2.

Now, all the monsters' healths are 0.
We cannot make all the monsters' health drop to 0 or below with just one bomb.

Sample Input 2

9 4 1
1 5
2 4
3 3
4 2
5 1
6 2
7 3
8 4
9 5

Sample Output 2

5

We should use five bombs at the coordinate 5.

Sample Input 3

3 0 1
300000000 1000000000
100000000 1000000000
200000000 1000000000

Sample Output 3

3000000000

Watch out for overflow.

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

/*
    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);
    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+1 , reg[i]-sumtemp);
        sum += reg[i]-sumtemp;
    }
    cout << sum << endl;
}