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 (GCC 5.4.1) (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <inttypes.h>

#define MAX (1 << 18) /* 262144 */
#define INF INT64_C(99999999999999999)

int64_t ki[MAX * 2 - 1];
int64_t ki_all[MAX * 2 - 1];

void ki_add_i(int idx, int qmin, int qmax, int smin, int smax, int64_t delta) {
	if (qmax <= smin || smax <= qmin) { /* はずれ */
		/* nop */
	} else if (qmin <= smin && smax <= qmax) { /* セグメントがクエリに完全に含まれる */
		ki_all[idx] += delta;
	} else {
		int smid = smin + (smax - smin) / 2;
		int lidx = idx * 2 + 1;
		int ridx = idx * 2 + 2;
		int64_t left, right;
		ki_all[lidx] += ki_all[idx];
		ki_all[ridx] += ki_all[idx];
		ki_all[idx] = 0;
		ki_add_i(lidx, qmin, qmax, smin, smid, delta);
		ki_add_i(ridx, qmin, qmax, smid, smax, delta);
		left = ki[lidx] + ki_all[lidx];
		right = ki[ridx] + ki_all[ridx];
		ki[idx] = left >= right ? left : right;
	}
}

void ki_add(int min, int max, int64_t delta) {
	ki_add_i(0, min, max, 0, MAX, delta);
}

int64_t ki_max_i(int idx, int qmin, int qmax, int smin, int smax) {
	if (qmax <= smin || smax <= qmin) { /* はずれ */
		return -INF;
	} else if (qmin <= smin && smax <= qmax) { /* セグメントがクエリに完全に含まれる */
		return ki[idx] + ki_all[idx];
	} else {
		int smid = smin + (smax - smin) / 2;
		int lidx = idx * 2 + 1;
		int ridx = idx * 2 + 2;
		int64_t left = ki_max_i(lidx, qmin, qmax, smin, smid);
		int64_t right = ki_max_i(ridx, qmin, qmax, smid, smax);
		return (left >= right ? left : right) + ki_all[idx];
	}
}

int64_t ki_max(int min, int max) {
	return ki_max_i(0, min, max, 0, MAX);
}

struct mon {
	int X, H;
};

int cmp(const void* x, const void* y) {
	int a = ((const struct mon*)x)->X, b = ((const struct mon*)y)->X;
	return a < b ? -1 : a > b;
}

int N, D, A;
struct mon m[271828];

/* 座標がzahyo以下の右端のやつを求める */
int kugyu(int zahyo) {
	int yes = 0, no = N - 1;
	if (m[no].X <= zahyo) return no;
	if (zahyo < m[yes].X) return -1;
	while (yes + 1 < no) {
		int mid = yes + (no - yes) / 2;
		if (m[mid].X <= zahyo) yes = mid; else no = mid;
	}
	return yes;
}

int tasu(int a, int b) {
	return b > INT_MAX - a ? INT_MAX : (a + b);
}

int main(void) {
	int i;
	int64_t count = 0;
	if (scanf("%d%d%d", &N, &D, &A) != 3) return 1;
	for (i = 0; i < N; i++) {
		if (scanf("%d%d", &m[i].X, &m[i].H) != 2) return 1;
	}
	qsort(m, N, sizeof(*m), cmp);
	for (i = 0; i < N; i++) {
		ki_add(i, i + 1, m[i].H);
	}
	for (i = 0; i < N; i++) {
		int64_t left = ki_max(i, i + 1);
		if (left > 0) {
			int64_t use = (left + A - 1) / A;
			int migi = kugyu(tasu(tasu(m[i].X, D), D));
			count += use;
			if (i <= migi) ki_add(i, migi + 1, -A * use);
		}
	}
	printf("%" PRId64 "\n", count);
	return 0;
}