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: Wrong Answer)

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

int max(int x, int y) {
	if(x > y)
		return x;
	return y;
}

// モンスターを座標の小さい順にソート
void mergesort(int n, int *x, int *h) {
	if(n < 2)
		return;
	mergesort(n/2, x, h);
	mergesort(n - n/2, x + n/2, h + n/2);
	int *x_tmp = malloc(sizeof(int)*n);
	int *h_tmp = malloc(sizeof(int)*n);
	int i = 0;
	int j = 0;
	while(i + j < n)
		if(n/2 <= i) {
			*(x_tmp + i + j) = *(x + n/2 + j);
			*(h_tmp + i + j) = *(h + n/2 + j);
			j++;
		} else if(n - n/2 <= j) {
			*(x_tmp + i + j) = *(x + i);
			*(h_tmp + i + j) = *(h + i);
			i++;
		} else if(*(x + i) < *(x + n/2 + j)) {
			*(x_tmp + i + j) = *(x + i);
			*(h_tmp + i + j) = *(h + i);
			i++;
		} else {
			*(x_tmp + i + j) = *(x + n/2 + j);
			*(h_tmp + i + j) = *(h + n/2 + j);
			j++;
		}
	for(i = 0; i < n; i++) {
		*(x + i) = *(x_tmp + i);
		*(h + i) = *(h_tmp + i);
	}
	free(x_tmp);
	free(h_tmp);
}

// 長さnの整列済み配列aで、要素iはp以上だが要素i-1はpより小さいようなiを返す
int binarysearch(int n, int *a, int p) {
	if(n < 1)
		return 0;
	if(p <= *(a + 0))
		return 0;
	if(*(a + n - 1) < p)
		return n;
	if(p <= *(a + n/2))
		return binarysearch(n/2, a, p);
	return n/2 + binarysearch(n - n/2, a + n/2, p);
}

int main(void) {
	int n, d, a, i;
	scanf("%d%d%d", &n, &d, &a);
	int *x = malloc(sizeof(int)*n);
	int *h = malloc(sizeof(int)*n);
	for(i = 0; i < n; i++)
		scanf("%d%d", x + i, h + i);
	mergesort(n, x, h);
	long *sum = malloc(sizeof(long)*n);
	*(sum + 0) = (*(h + 0) + a - 1)/a;
	for(i = 1; i < n; i++) {
		int border = binarysearch(i, x, *(x + i) - 2*d);
		if(border == 0)
			*(h + i) -= max((*(sum + i - 1))*a, 0);
		else
			*(h + i) -= max((*(sum + i - 1) - *(sum + border - 1))*a, 0);
		*(sum + i) = *(sum + i - 1) + (*(h + i) + a - 1)/a;
	}
	printf("%ld\n", *(sum + n - 1));
	free(x);
	free(h);
	free(sum);
	return 0;
}