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)

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

#define int __int128

void read(int &x) {
	x = 0; int c = getchar();
	while (c <= 32) c = getchar();
	while (c > 32) {
		x = x * 10 + c - '0';
		c = getchar();
	}
}

void write(int x) {
	if (x >= 10) write(x / 10);
	putchar(x % 10 + '0');
}

const int N = 1 << 24;
const int inf = ((int) 1) << 120;
const int infi = 0x3f3f3f3f * 3LL;

struct SegT {
	int add[N], mx[N], tot;
	int lson[N], rson[N];
	int rt;

	int nwnode() {
		int x = ++ tot;
		add[x] = 0;
		mx[x] = 0;
		lson[x] = rson[x] = 0;
		return x;
	}

	void pushdown(int i, int l) {
		mx[i] += add[i];
		if (l > 1) {
			if (!lson[i]) lson[i] = nwnode();
			if (!rson[i]) rson[i] = nwnode();
			add[lson[i]] += add[i];
			add[rson[i]] += add[i];
		}
		add[i] = 0;
	}

	void upd(int l, int r, int v, int &x, int a = 0, int b = infi) {
		if (!x) x = nwnode();
		pushdown(x, b - a);
		if (l <= a && b <= r) {
			add[x] += v;
			pushdown(x, b - a); return ;
		}
		if (r <= a || b <= l) return ;
		int m = (a + b) >> 1;
		upd(l, r, v, lson[x], a, m);
		upd(l, r, v, rson[x], m, b);
		mx[x] = -inf;
		if (lson[x]) mx[x] = max(mx[x], mx[lson[x]]);
		if (rson[x]) mx[x] = max(mx[x], mx[rson[x]]);
	}

	int binary(int i, int a = 0, int b = infi) {
		if (!i) return -1;
		pushdown(i, b - a);
		if (mx[i] <= 0) return -1;
		if (a + 1 == b) return a;
		int m = (a + b) >> 1;
		if (lson[i] && mx[lson[i]] > 0)
			return binary(lson[i], a, m);
		return binary(rson[i], m, b);
	}

	int qry(int l, int r, int x, int a = 0, int b = infi) {
		if (!x) return -inf;
		pushdown(x, b - a);
		if (l <= a && b <= r) return mx[x];
		if (r <= a || b <= l) return -inf;
		int m = (a + b) >> 1;
		return max(qry(l, r, lson[x], a, m), qry(l, r, rson[x], m, b));
	}
} segt;

int n, D, A;

signed main() {
	read(n); read(D); read(A);
	// n = 2e5; D = 0; A = 1;
	for (int i = 0; i < n; ++ i) {
		int X, H;
		read(X); read(H);
		// X = 1e9 - i; H = 1e9;
		segt.upd(X, X + 1, H, segt.rt);
	}
	int x;
	int ans = 0;
	while (~(x = segt.binary(segt.rt))) {
		int h = segt.qry(x, x + 1, segt.rt);
		int tms = (h + A - 1) / A;
		// cerr << "at " << x + D << " use " << tms << " times." << endl;
		segt.upd(x, x + 2 * D + 1, -tms * A, segt.rt);
		ans += tms;
	}
	write(ans); puts("");
	return 0;
}