output_description: Print the minimum number of bombs needed to win.
  
  * * *
input_description: Input is given from Standard Input in the following format:
  
      
      
      N D A
      X_1 H_1
      :
      X_N H_N
attempt: import operator
  import os
  import sys
  
  if os.getenv("LOCAL"):
      sys.stdin = open("_in.txt", "r")
  
  sys.setrecursionlimit(10**9)
  INF = float("inf")
  IINF = 10**18
  MOD = 10**9 + 7
  
  
  # MOD = 998244353
  
  
  class LazySegmentTree:
      # http://tsutaj.hatenablog.com/entry/2017/03/29/204841
      def __init__(self, size, fn=operator.add, default=None, initial_values=None):
          """
          :param int size:
          :param callable fn: 区間に適用する関数。引数を 2 つ取る。min, max, operator.xor など
          :param default:
          :param list initial_values:
          """
          default = default or 0
  
          # size 以上である最小の 2 冪を size とする
          self._size = 1 << (size - 1).bit_length()
          self._fn = fn
  
          self._lazy = [0] * (self._size * 2 - 1)
          self._tree = [default] * (self._size * 2 - 1)
          if initial_values:
              i = self._size - 1
              for v in initial_values:
                  self._tree[i] = v
                  i += 1
              i = self._size - 2
              while i >= 0:
                  self._tree[i] = self._fn(self._tree[i * 2 + 1], self._tree[i * 2 + 2])
                  i -= 1
  
      def add(self, from_i, to_i, value, k=0, L=None, r=None):
          """
          [from_i, to_i) を、それぞれの値と value に fn を適用した値で更新する
          :param int from_i:
          :param int to_i:
          :param int value:
          :param int k: self._tree のインデックス
          :param int L:
          :param int r:
          :return:
          """
          L = 0 if L is None else L
          r = self._size if r is None else r
  
          self._eval(k, L, r)
  
          # 範囲外
          if to_i <= L or r <= from_i:
              return
  
          if from_i <= L and r <= to_i:
              # 完全に被覆してる
              self._lazy[k] += (r - L) * value
              self._eval(k, L, r)
          else:
              # 中途半端
              self.add(from_i, to_i, value, k * 2 + 1, L, (L + r) // 2)
              self.add(from_i, to_i, value, k * 2 + 2, (L + r) // 2, r)
              self._tree[k] = self._fn(self._tree[k * 2 + 1], self._tree[k * 2 + 2])
  
      def _eval(self, k, L, r):
          """
          遅延配列の値を評価する
          :param k:
          :param L:
          :param r:
          """
          if self._lazy[k] != 0:
              # 本体を更新
              self._tree[k] += self._lazy[k]
              # 一番下じゃなければ伝播させる
              if r - L > 1:
                  self._lazy[k * 2 + 1] += self._lazy[k] >> 1
                  self._lazy[k * 2 + 2] += self._lazy[k] >> 1
              self._lazy[k] = 0
  
      def get(self, from_i, to_i, k=0, L=None, r=None):
          """
          [from_i, to_i) に fn を適用した結果を返す
          :param int from_i:
          :param int to_i:
          :param int k: self._tree[k] が、[L, r) に fn を適用した結果を持つ
          :param int L:
          :param int r:
          :return:
          """
          L = 0 if L is None else L
          r = self._size if r is None else r
  
          self._eval(k, L, r)
  
          if from_i <= L and r <= to_i:
              return self._tree[k]
  
          if to_i <= L or r <= from_i:
              return None
  
          ret_L = self.get(from_i, to_i, k * 2 + 1, L, (L + r) // 2)
          ret_r = self.get(from_i, to_i, k * 2 + 2, (L + r) // 2, r)
          if ret_L is None:
              return ret_r
          if ret_r is None:
              return ret_L
          return self._fn(ret_L, ret_r)
  
      def __len__(self):
          return self._size
  
  
  N, D, A = list(map(int, sys.stdin.buffer.readline().split()))
  XH = [list(map(int, sys.stdin.buffer.readline().split())) for _ in range(N)]
  
  XH.sort()
  X = []
  H = []
  for x, h in XH:
      X.append(x)
      H.append(h)
  
  lr = []
  r = 0
  for l in range(N):
      while r < N and X[r] <= X[l] + D * 2:
          r += 1
      lr.append((l, r))
  
  imos = [0] * (N + 1)
  cum = 0
  ans = 0
  for l, r in lr:
      cum += imos[l]
      h = H[l] - cum
      if h > 0:
          cnt = (h + A - 1) // A
          cum += cnt * A
          imos[r] -= cnt * A
          ans += cnt
  print(ans)
  
problem_description: 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.
samples: [{"input": "3 3 2\n    1 2\n    5 4\n    9 2", "output": "2\n    \n\nFirst, let us use a bomb at the coordinate 4 to decrease the first and second\nmonsters' health by 2.\n\nThen, use a bomb at the coordinate 6 to decrease the second and third\nmonsters' health by 2.\n\nNow, all the monsters' healths are 0. We cannot make all the monsters' health\ndrop to 0 or below with just one bomb.\n\n* * *"}, {"input": "9 4 1\n    1 5\n    2 4\n    3 3\n    4 2\n    5 1\n    6 2\n    7 3\n    8 4\n    9 5", "output": "5\n    \n\nWe should use five bombs at the coordinate 5.\n\n* * *"}, {"input": "3 0 1\n    300000000 1000000000\n    100000000 1000000000\n    200000000 1000000000", "output": "3000000000\n    \n\nWatch out for overflow."}]