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 Rust (1.15.1) (judge verdict: Accepted)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
use std::str::FromStr;
use std::fmt::Debug;
#[allow(dead_code)]
fn read_as_vec<T>() -> Vec<T>
where T: FromStr, <T as FromStr>::Err : Debug{
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim().split_whitespace().map(|c| T::from_str(c).unwrap()).collect()

}

#[derive(Debug)]
struct SegmentTree{
    v: Vec<(i64, i64)>,
    n: usize
}

impl SegmentTree{
    pub fn new(a: Vec<i64>) -> SegmentTree{
        let mut n = 1;
        while n < a.len(){
            n *= 2;
        }
        let mut v: Vec<(i64, i64)> = vec![(0, 0);2*n-1];
        for i in 0..a.len(){
            v[n - 1 + i] = (a[i], 0);
        }

        for i in (0..n-1).rev(){
            v[i].0 = v[i*2+1].0 + v[i*2+2].0;
        }

        SegmentTree{
            v,
            n
        }
    }

    fn eval_lazily(&mut self, k: usize, l: usize, r: usize){
        if self.v[k].1 == 0{
            return;
        }
        self.v[k].0 += self.v[k].1;

        // if not leaf
        if r-l > 1{
            self.v[2*k+1].1 += self.v[k].1/2;
            self.v[2*k+2].1 += self.v[k].1/2;
        }

        self.v[k].1 = 0;
    }

    pub fn update(&mut self, val: i64, a: usize, b: usize){
        self._update(0, a, b, val, 0, self.v.len()/2+1);
    }

    fn _update(&mut self, k: usize, a: usize, b: usize,
               val: i64, l: usize, r: usize){
        // node[k] covers [l, r)
        self.eval_lazily(k, l, r);
        if b <= l || r <= a{
            return;
        }

        if a <= l && r <= b{
            self.v[k].1 += (r-l) as i64 * val;
            self.eval_lazily(k, l, r);
        }else{
            self._update(2*k+1, a, b, val, l, (l+r)/2);
            self._update(2*k+2, a, b, val, (l+r)/2, r);
            self.v[k].0 = self.v[2*k+1].0 + self.v[2*k+2].0;
        }

    }

    pub fn get_sum(&mut self, a: usize, b: usize) -> i64{
        self._get_sum(a, b, 0, 0, (self.v.len()+1)/2)
    }

    fn _get_sum(&mut self, a: usize, b: usize, k: usize,
                l: usize, r: usize) -> i64{
        if b <= l || r <= a{
            return 0;
        }

        self.eval_lazily(k, l, r);

        if a <= l && r <= b{
            return self.v[k].0;
        }

        self._get_sum(a, b, 2*k+1, l, (l+r)/2) +
            self._get_sum(a, b, 2*k+2, (l+r)/2, r)
    }
}

fn main(){
    let line = read_as_vec::<usize>();
    let (n, d, a) = (line[0], line[1] as i64, line[2] as i64);

    let mut monsters: Vec<(i64, i64)> = vec![];

    for _ in 0..n{
        let line = read_as_vec::<i64>();
        monsters.push((line[0], line[1]));
    }

    monsters.sort();
    let mut health = vec![];
    for i in 0..n{
        health.push(monsters[i].1);
    }
    let mut sg = SegmentTree::new(health);
    //shakutori
    let mut r: usize = 0;
    let mut ans: i64 = 0;

    for l in 0..n{
        let (x, _) = (monsters[l].0, monsters[l].1);

        while r < n && monsters[r].0 <= (x as i64+ 2*d) as i64{
            r += 1;
        }
        let remain = sg.get_sum(l, l+1);
        if remain <= 0{
            continue;
        }
        let num_bomb = (remain+a-1)/a;
        sg.update(-num_bomb*a, l, r);
        ans += num_bomb;
    }
    println!("{}", ans);
}

*/

fn main() {
    let exe = "./binXXXXXX";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";