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 <string.h>
#include <stdlib.h>
#include <stdint.h> // uint64_t

#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) > (b) ? (b) : (a))

int get_int(void) {
  int num;
  scanf("%d", &num);
  return num;
}

int get_int2(int64_t *a1, int *a2) {
  scanf("%lld %d", a1, a2);
  return 0;
}

int get_int3(int *a1, int64_t *a2, int *a3) {
  scanf("%d %lld %d", a1, a2, a3);
  return 0;
}

struct monster {
    int64_t pos;
    int hp;
};

int asc_by_pos(const void *a1, const void *a2) {
    struct monster *ma1 = (struct monster*)a1;
    struct monster *ma2 = (struct monster*)a2;
    return ma1->pos - ma2->pos;
}

#define NUM_MAX 200000
#define NUM2_MAX (1<<18)
#define ROOT_NODE 1
#define INF ((int64_t)(3e+9)+1)

struct range {
    int start;
    int end;
};

int64_t get_val(int64_t* seg, int num, int idx) {
    int node = num+idx;
    int64_t ans = 0;
    while(node) {
        ans += seg[node];
        node /= 2;
    }
    return ans;
}

int is_contain(struct range this, struct range box) {
    return box.start <= this.start && box.end >= this.end;
}

int is_overlap(struct range r1, struct range r2) {
    return r1.end >= r2.start && r2.end >= r1.start;
}

void add_range(int64_t *seg, int64_t val, struct range r, int node, struct range nr) {
#ifdef DEBUG
    printf("add_range(seg, %lld, r, %d)\n", val, node);
#endif
    if(is_contain(nr, r)) {seg[node] += val; return;}
    if(!is_overlap(r, nr)) return;
    struct range left = {nr.start, (nr.start+nr.end)/2};
    struct range right = {left.end+1, nr.end};
    add_range(seg, val, r, node*2, left);
    add_range(seg, val, r, node*2+1, right);
    return;
}

#define ROOT_NODE 1
int main(void) {
    int num, attack;
    int64_t range;
    static struct monster mons[NUM_MAX+1];
    get_int3(&num, &range, &attack);
    range *= 2;
    int num2 = 1;
    while(num > num2) num2 *= 2;

    int i;
    for(i = 0; i < num; i++) {
        get_int2(&mons[i].pos, &mons[i].hp);
    }
    mons[num] = (struct monster){INF, 0}; // guard
    qsort(mons, num, sizeof(struct monster), asc_by_pos);

    static int64_t seg[NUM2_MAX*2];
    for(i = 0; i < num; i++) {
        seg[i+num2] = mons[i].hp;
    }

    int left;
    int right = 0;
    int64_t ans = 0;

    struct range whole = {0, num2-1};
    for(left = 0; left < num+1; left++) {
        if(left == right) { right++; }
        int64_t rem = get_val(seg, num2, left);
        if(rem <= 0) continue; // if no hit point, break;
        // ensure that mons[left] should be attacked
        for(;right < num+1; right++) {
            if(mons[left].pos + range < mons[right].pos) break;
        }
#ifdef DEBUG
        printf("[%d, %d)\n", left, right);
#endif
        // attack
        int64_t cnt = (rem-1)/attack + 1;
        int64_t damage = (int64_t)attack * cnt;
        struct range r = {left, right-1};
        add_range(seg, -damage, r, ROOT_NODE, whole);
        ans += cnt;
    }
    printf("%lld\n", ans);

    return 0;
}