Silver Fox is fighting with N monsters. The monsters are standing in a row on a number line. The i-th monster at coordinate X_i has health H_i. Silver Fox can use bombs to attack the monsters. Using a bomb at coordinate x decreases the health of monsters between x-D and x+D (inclusive) by A. Silver Fox wins when all monsters' health becomes 0 or below. Find the minimum number of bombs needed to win.

Constraints:
- 1 ≤ N ≤ 2 × 10^5
- 0 ≤ D ≤ 10^9
- 1 ≤ A ≤ 10^9
- 0 ≤ X_i ≤ 10^9
- 1 ≤ H_i ≤ 10^9
- X_i are distinct
- All input values are integers

Input:
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, use a bomb at coordinate 4 to decrease the first and second monsters' health by 2. Then, use a bomb at coordinate 6 to decrease the second and third monsters' health by 2. Now, all monsters' healths are 0.

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
Use five bombs at coordinate 5.

Sample Input 3:
3 0 1
300000000 1000000000
100000000 1000000000
200000000 1000000000

Sample Output 3:
3000000000
Watch out for overflow.

# Buggy version:
from collections import deque
from math import ceil

# n个怪物，d杀伤半径，a杀伤值
n, d, a = map(int,input().split())

ms = sorted([(pos, ceil(hp / a)) for pos, hp in [map(int, input().split()) for i in range(n)])
 
bombs = deque()
 
ans = 0
valid_bomb = 0
for pos, hp in ms:
  # 查看队列里的bomb是否对当前怪物有效
  while que and que[0][0] < pos:
    bomb_border, bomb_cnt = bombs.popleft()
    valid_bomb -= bomb_cnt
  
  # 还需新加多少bomb才能灭掉当前怪物
  bomb_cnt = max(0, hp - valid_bomb)
  valid_bomb += bomb_cnt
  ans += bomb_cnt
  
  # 新加的bomb放入队列
  if bomb_cnt > 0:
    que.append([pos + d * 2, bomb_cnt])
 
print(ans)  


# Fixed version:
from collections import deque
from math import ceil

# n个怪物，d杀伤半径，a杀伤值
n, d, a = map(int,input().split())

ms = [map(int, input().split()) for i in range(n)]
ms = sorted([(pos, ceil(hp / a)) for pos, hp in ms])
 
bombs = deque()
 
ans = 0
valid_bomb = 0
for pos, hp in ms:
  # 查看队列里的bomb是否对当前怪物有效
  while bombs and bombs[0][0] < pos:
    bomb_border, bomb_cnt = bombs.popleft()
    valid_bomb -= bomb_cnt
  
  # 还需新加多少bomb才能灭掉当前怪物
  bomb_cnt = max(0, hp - valid_bomb)
  valid_bomb += bomb_cnt
  ans += bomb_cnt
  
  # 新加的bomb放入队列
  if bomb_cnt > 0:
    bombs.append([pos + d * 2, bomb_cnt])
 
print(ans)

# Buggy version:
import math
from collections import deque
N,D,A = map(int,input().split())
monsters = [ list(map(int,input().split())) for _ in range(N) ]
monsters = [ [x, math.ceil(h/A)] for x,h in monsters ]

print(monsters)

que = deque()
cur = 0
ans = 0
for x,h in monsters:
  while que and x > que[0][0]:
    _,n = que.popleft()
    cur -= n

  need = max(0, h-cur)
  ans += need
  cur += need

  if h:
    # 対象のモンスターを最も左端にいることを想定
    que.append([x+2*D, need])

print(ans)

# Fixed version:
import math
from collections import deque
N,D,A = map(int,input().split())
monsters = sorted([ list(map(int,input().split())) for _ in range(N) ])
monsters = [ [x, math.ceil(h/A)] for x,h in monsters ]
# print(monsters)
que = deque()
cur = 0
ans = 0
for x,h in monsters:
  while que and x > que[0][0]:
    _,n = que.popleft()
    cur -= n

  need = max(0, h-cur)
  ans += need
  cur += need

  if h:
    # 対象のモンスターを最も左端にいることを想定
    que.append([x+2*D, need])

print(ans)

# Buggy version:
from collections import deque

n,d,a = map(int, input().split())
xhl = []
for _ in range(n):
    x,h = map(int, input().split())
    cnt = (h-1)//a + 1
    xhl.append((x,cnt))

attack_q = deque([])
attack_sum = 0
ans = 0
for x,h in xhl:
    while attack_q and attack_q[0][0] < x:
        poped_cnt = attack_q.popleft()[1]
        attack_sum -= poped_cnt
    rem = h-attack_sum
    if rem <= 0:
        continue
    attack_sum += rem
    ans += rem
    attack_q.append((x+2*d, rem))

print(ans)

# Fixed version:
from collections import deque

n,d,a = map(int, input().split())
xhl = []
for _ in range(n):
    x,h = map(int, input().split())
    cnt = (h-1)//a + 1
    xhl.append((x,cnt))

xhl.sort()

attack_q = deque([])
attack_sum = 0
ans = 0
for x,h in xhl:
    # print('----',((x,h)))
    # print(attack_q)
    # print(attack_sum)
    while attack_q and attack_q[0][0] < x:
        poped_cnt = attack_q.popleft()[1]
        attack_sum -= poped_cnt
    # print(attack_q)
    # print(attack_sum)
    rem = h-attack_sum
    if rem <= 0:
        continue
    attack_sum += rem
    ans += rem
    attack_q.append((x+2*d, rem))
    # print(rem)

print(ans)
# print(xhl)

# Buggy version:
from collections import deque
n,d,a=map(int,input().split())
xh=[map(int,input().split()) for _ in range(n)]
xh.sort()
D=2*D
ans=0
total=0
q=deque()
for i in range(n):
  x,h=xh[i]
  while len(q)>=1 and x>q[0][0]:
    total-=q.popleft()[1]
  h-=total
  if h>0:
    num=(h-h%a)//a
    damage=a*nim
    ans+=num
    total+=damage
    q.append([x+D,damage])
print(ans)

# Fixed version:
from collections import deque
n,d,a=map(int,input().split())
xh=[list(map(int,input().split())) for _ in range(n)]
xh.sort()
d=2*d
ans=0
total=0
q=deque()
for i in range(n):
  x,h=xh[i]
  while len(q)>=1 and x>q[0][0]:
    total-=q.popleft()[1]
  h-=total
  if h>0:
    num=(h-1)//a+1
    damage=a*num
    ans+=num
    total+=damage
    q.append([x+d,damage])
print(ans)

# Buggy version:
from collections import deque
n, d, a = map(int, input().split())

mons = []

for i in range(n):
    x, h = map(int, input().split())
    mons.append((x, h))

mons = sorted(mons)

print(mons)

q = deque()

dm_sum = 0

ans = 0

for i in range(n):
    while dm_sum > 0:
        if q[0][0] < mons[i][0]:
            cur = q.popleft()
            dm_sum -= cur[1]
        else:
            break
    if mons[i][1] <= dm_sum:
        continue
    rem = mons[i][1] - dm_sum
    at_num = rem // a
    if rem % a != 0:
        at_num += 1
    ans += at_num

    q.append((mons[i][0] + 2 * d, at_num*a))
    dm_sum += at_num*a

print(ans)


# Fixed version:
from collections import deque
n, d, a = map(int, input().split())

mons = []

for i in range(n):
    x, h = map(int, input().split())
    mons.append((x, h))

mons = sorted(mons)

q = deque()

dm_sum = 0

ans = 0

for i in range(n):
    while dm_sum > 0:
        if q[0][0] < mons[i][0]:
            cur = q.popleft()
            dm_sum -= cur[1]
        else:
            break
    if mons[i][1] <= dm_sum:
        continue
    rem = mons[i][1] - dm_sum
    at_num = rem // a
    if rem % a != 0:
        at_num += 1
    ans += at_num

    q.append((mons[i][0] + 2 * d, at_num*a))
    dm_sum += at_num*a

print(ans)

# Buggy version:
from math import ceil
from collections import deque

n, d, a = map(int, input().split())
m = [list(map(int, input().split())) for _ in range(n)]
m = [[x, ceil(h/a)] for x, h in m]

acc_damage = 0
que = deque()
ans = 0
for x, h in m:
    while que and x > que[0][0]:
        limit, damage = que.popleft()
        acc_damage -= damage

    rest_h = max(0, h - acc_damage)
    ans += rest_h
    acc_damage += rest_h

    if rest_h:
        que.append([x + 2 * d, rest_h])

print(ans)

# Fixed version:
from math import ceil
from collections import deque

n, d, a = map(int, input().split())
m = sorted([list(map(int, input().split())) for _ in range(n)])
m = [[x, ceil(h / a)] for x, h in m]

acc_damage = 0
que = deque()
ans = 0
for x, h in m:
    while que and x > que[0][0]:
        limit, damage = que.popleft()
        acc_damage -= damage

    need = max(0, h - acc_damage)
    ans += need
    acc_damage += need

    if need:
        que.append([x + 2 * d, need])

print(ans)

# Buggy version:
import sys, heapq
input = sys.stdin.readline
N, D, A = [int(_) for _ in input().split()]
XH = [[int(_) for _ in input().split()] for _ in range(N)]
He = [[2 * x, h, 0] for x, h in XH]
heapq.heapify(He)
now = 0
ans = 0
while He:
    x, h, t = heapq.heappop(He)
    if t:
        now -= h
    else:
        if h - D * now > 0:
            diff = (h - now - 1) // A + 1
            now += diff
            ans += diff
            heapq.heappush(He, [x + 4 * D + 1, diff, 1])
print(ans)


# Fixed version:
import sys, heapq
input = sys.stdin.readline
N, D, A = [int(_) for _ in input().split()]
XH = [[int(_) for _ in input().split()] for _ in range(N)]
He = [[2 * x, h, 0] for x, h in XH]
heapq.heapify(He)
now = 0
ans = 0
while He:
    x, h, t = heapq.heappop(He)
    if t:
        now -= h
    else:
        if h - A * now > 0:
            diff = (h - A * now - 1) // A + 1
            now += diff
            ans += diff
            heapq.heappush(He, [x + 4 * D + 1, diff, 1])
print(ans)

# Buggy version:
import math
n, d, a = map(int,input().split())
e = [[] for i in range(n)]
for i in range(n):
    x, h = map(int,input().split())
    e[i] = [x,h]
num = 0

e.sort()
sd = [0 for i in range(n)]
l = [i for i in range(n)]
for i in range(n):
    for j in range(l[i-1],i):
        if e[i][0]-e[j][0] <= 2*d:
            l[i] = j
            break

for i in range(n):
    res = x[i][1] - sd[i-1] + sd[l[i]-1]
    if res < 0:
        sd[i] = sd[i-1]
    else:
        k = math.ceil(res/a)
        sd[i] = sd[i-1]+k*a
        num += k
        
print(num)


# Fixed version:
import math
n, d, a = map(int,input().split())
e = [[] for i in range(n)]
for i in range(n):
    x, h = map(int,input().split())
    e[i] = [x,h]
num = 0

e.sort()
sd = [0 for i in range(n)]
l = [i for i in range(n)]
for i in range(n):
    for j in range(l[i-1],i):
        if e[i][0]-e[j][0] <= 2*d:
            l[i] = j
            break

for i in range(n):
    res = e[i][1] - sd[i-1] + sd[l[i]-1]
    if res < 0:
        sd[i] = sd[i-1]
    else:
        k = math.ceil(res/a)
        sd[i] = sd[i-1]+k*a
        num += k

print(num)

# Buggy version:
import math
import collections
N, D, A = map(int, input().split())

XH = [tuple(map(int, input().split())) for i in range(N)]

q = collections.deque()
c = 0
ans = 0
for x, h in XH:
    while(q and q[0][0] < x):
        c -= q[0][1]
        q.popleft()

    h -= c * A
    ans += math.ceil(h/A)
    c += math.ceil(h/A)
    q.append((x+2*D, math.ceil(x/A)))
    #print(ans, x)
print(ans)


# Fixed version:
import math
import collections
N, D, A = map(int, input().split())

XH = [tuple(map(int, input().split())) for i in range(N)]
XH.sort()
q = collections.deque()
c = 0
ans = 0
for x, h in XH:
    while(q and q[0][0] < x):
        c -= q[0][1]
        q.popleft()
    h -= c * A
    if h < 0:
        h = 0
    ans += math.ceil(h/A)
    c += math.ceil(h/A)

    q.append((x+2*D, math.ceil(h/A)))

print(ans)

# Buggy version:
import sys
input = sys.stdin.readline
import bisect
import collections
from collections import deque
n,d,a= map(int, input().split())
x= [list(map(int, input().split())) for i in range(n)]

x.sort()
y=[]
for i in range(n):
    y.append(x[i][0])
    x[i][1]=-(-x[i][1]//a)

# どのモンスターまで倒したか管理しながら進める。
# 累積ダメージを管理
qq=deque([])
ans=0
atk=0
for i in range(n):
    w=x[i][1]
    # iがダメージの有効期限を超過している場合
    while qq and i > qq[0][0]:
        atk-=qq[0][1]
        qq.popleft()

    if w-atk>0:
        ans+=w-atk
        q=bisect.bisect_right(y,x[i][0]+2*d)-1
        # 有効期限　ダメージ
        qq.append([q,w-atk])
        atk += w - atk
        print(atk,qq)
print(ans)

# Fixed version:
import sys
input = sys.stdin.readline
import bisect
import collections
from collections import deque
n,d,a= map(int, input().split())
x= [list(map(int, input().split())) for i in range(n)]

x.sort()
y=[]
for i in range(n):
    y.append(x[i][0])
    x[i][1]=-(-x[i][1]//a)

# どのモンスターまで倒したか管理しながら進める。
# 累積ダメージを管理
qq=deque([])
ans=0
atk=0
for i in range(n):
    w=x[i][1]
    # iがダメージの有効期限を超過している場合
    while len(qq)>0 and i > qq[0][0]:
        atk-=qq[0][1]
        qq.popleft()

    if w-atk>0:
        ans+=w-atk
        q=bisect.bisect_right(y,x[i][0]+2*d)-1
        # 有効期限　ダメージ
        qq.append([q,w-atk])
        atk += w - atk
print(ans)

# Buggy version:
n, d, a = map(int, input().split())
l = [[0, 0] for _ in range(n)]
for i in range(n):
  x, h = map(int, input().split())
  l[i][0] = x
  l[i][1] = h
  
l.sort()
print(l)
from collections import deque
d = 2*d
q = deque([])
total = 0

ans = 0
for i in range(n):
  x = l[i][0]
  h = l[i][1]
  if q:
    while q[0][0] < x:
      total -= q[0][1]
      q.popleft()
      if not q:
        break
  h -= total
  if h > 0:
    num = (h+a-1)//a
    ans += num
    damage = num*a
    total += damage
    q.append([x+d, damage])

print(ans)

# Fixed version:
n, d, a = map(int, input().split())
l = [[0, 0] for _ in range(n)]
for i in range(n):
  x, h = map(int, input().split())
  l[i][0] = x
  l[i][1] = h
  
l.sort()
from collections import deque
d = 2*d
q = deque([])
total = 0

ans = 0
for i in range(n):
  x = l[i][0]
  h = l[i][1]
  if q:
    while q[0][0] < x:
      total -= q[0][1]
      q.popleft()
      if not q:
        break
  h -= total
  if h > 0:
    num = (h+a-1)//a
    ans += num
    damage = num*a
    total += damage
    q.append([x+d, damage])

print(ans)

# Buggy version:
import bisect
import sys
input = sys.stdin.readline
from collections import defaultdict
class Bit:
  def __init__(self, n):
    self.size = n
    self.tree = [0] * (n + 1)

  def sum(self, i):
    s = 0
    while i > 0:
        s += self.tree[i]
        i -= i & -i
    return s

  def add(self, i, x):
    while i <= self.size:
      self.tree[i] += x
      i += i & -i
n,d,a = map(int,input().split())
xh = [list(map(int,input().split())) for i in range(n)]
for i in range(n):
  xh[i][1] = (xh[i][1]+a-1)//a
xh.sort()
x = [xh[i][0] for i in range(n)]
remain = [xh[i][1] for i in range(n)]
ans = 0
bit = Bit(n)
for i in range(n):
  if bit.sum(i+1) >= remain[i]:
    continue
  br = bisect.bisect_right(x,x[i]+2*d)
  ans += remain[i]
  bit.add(i+1,remain[i])
  bit.add(br+1,-remain[i])
print(ans)

# Fixed version:
import bisect
import sys
input = sys.stdin.readline
from collections import defaultdict
class Bit:
  def __init__(self, n):
    self.size = n
    self.tree = [0] * (n + 1)

  def sum(self, i):
    s = 0
    while i > 0:
        s += self.tree[i]
        i -= i & -i
    return s

  def add(self, i, x):
    while i <= self.size:
      self.tree[i] += x
      i += i & -i
n,d,a = map(int,input().split())
xh = [list(map(int,input().split())) for i in range(n)]
for i in range(n):
  xh[i][1] = (xh[i][1]+a-1)//a
xh.sort()
x = [xh[i][0] for i in range(n)]
remain = [xh[i][1] for i in range(n)]
ans = 0
bit = Bit(n+1)

for i in range(n):
  if bit.sum(i+1) >= remain[i]:
    continue
  br = bisect.bisect_right(x,x[i]+2*d)
  y = remain[i]-bit.sum(i+1)
  ans += y
  bit.add(i+1,y)
  bit.add(br+1,-y)
print(ans)

# Buggy version:
from collections import deque

# input
N, D, A = map(int, input().split())
XH = [tuple(map(int, input().split())) for _ in range(N)]

# process
XH.sort()
print(XH)

ans = 0
dq = deque()
dam = 0
for x, h in XH:
    while dq:
        x2, h2 = dq[0]
        if x > x2:
            dam -= h2
            dq.popleft()
        else:
            break

    h -= dam
    if h <= 0:
        continue

    c = -(-h//A)
    ans += c
    d = A*c
    dam += d
    dq.append((x+D*2, d))
    
# output
print(ans)


# Fixed version:
from collections import deque

# input
N, D, A = map(int, input().split())
XH = [tuple(map(int, input().split())) for _ in range(N)]

# process
XH.sort()
#print(XH)

ans = 0
dq = deque()
dam = 0
for x, h in XH:
    while dq:
        x2, h2 = dq[0]
        if x > x2:
            dam -= h2
            dq.popleft()
        else:
            break

    h -= dam
    if h <= 0:
#        print("x,h,dam: {},{},{}".format(x,h,dam))
        continue

    c = -(-h//A)
    ans += c
    d = A*c
    dam += d
    dq.append((x+D*2, d))
#    print("x,h,dam,ans,dq: {},{},{},{},{}".format(x,h,dam,ans,dq))
    
# output
print(ans)

# Buggy version:
from operator import itemgetter
import bisect
import math

N,d,a = map(int, input().split())
xh = sorted([list(map(int, input().split())) for i in range(N)], key=itemgetter(0))
x = []
for X,h in xh:
  x.append(X)
ans = 0
attack_start = [i for i in range(N)]
now = 0
cumsum = [0] * (N+1)
for L,(X,H) in enumerate(xh):
  R = bisect.bisect_right(x,X+2*d)
  for i in range(now,R):
    attack_start[i] = L
  now = R
  damage = (cumsum[L] - cumsum[attack_start[L]]) * a
  attack_time = max(0,math.ceil((H - damage) / a))
  ans += attack_time
  cumsum[L+1] = ans
print(ans)  
print(attack_start)
print(cumsum)


# Fixed version:
from operator import itemgetter
import bisect
import math

N,d,a = map(int, input().split())
xh = sorted([list(map(int, input().split())) for i in range(N)], key=itemgetter(0))
x = []
for X,h in xh:
  x.append(X)
ans = 0
attack_start = [i for i in range(N)]
now = 0
cumsum = [0] * (N+1)
for L,(X,H) in enumerate(xh):
  R = bisect.bisect_right(x,X+2*d)
  for i in range(now,R):
    attack_start[i] = L
  now = R
  damage = (cumsum[L] - cumsum[attack_start[L]]) * a
  attack_time = max(0,math.ceil((H - damage) / a))
  ans += attack_time
  cumsum[L+1] = ans
print(ans)

# Buggy version:
from collections import deque

N, D, A=map(int, input().split())
XH=[list(map(int, input().split())) for _ in range(N)]
XH.sort(key=lambda x:x[0])
total=0
q=deque()
ans=0

for i in range(N):
  X, H=XH[i]
  while len(q) and q[0][0]<X:
    total-=q.pop()[1]
  H-=total
  if H>0:
    attack_cnt=(H-1)//A+1
    ans+=attack_cnt
    damage=attack_cnt*A
    total+=damage
    q.append([X+2*D, damage])
print(ans)

# Fixed version:
from collections import deque

N, D, A=map(int, input().split())
XH=[list(map(int, input().split())) for _ in range(N)]
XH.sort(key=lambda x:x[0])
total=0
q=deque()
ans=0

for i in range(N):
  X, H=XH[i]
  while len(q) and q[0][0]<X:
    total-=q.popleft()[1]
  H-=total
  if H>0:
    attack_cnt=(H-1)//A+1
    ans+=attack_cnt
    damage=attack_cnt*A
    total+=damage
    q.append([X+2*D, damage])
print(ans)

# Buggy version:
from math import ceil
from collections import deque

N,D,A = map(int,input().split())
monsters = sorted([list(map(int,input().split())) for _ in range(N)])

q = deque([])
s = 0

ans = 0
for i in range(N):
  print(q)
  while len(q) > 0 and q[0][0] < monsters[i][0]:
    s -= q[0][1]
    q.popleft()

  h = monsters[i][1] - s * A
  if h > 0:
    num_bombs = ceil(h / A)

    q.append((monsters[i][0] + 2 * D, num_bombs))
    s += num_bombs
    ans += num_bombs
    
print(ans)


# Fixed version:
from math import ceil
from collections import deque

N,D,A = map(int,input().split())
monsters = sorted([list(map(int,input().split())) for _ in range(N)])

q = deque([])
s = 0

ans = 0
for i in range(N):
  while len(q) > 0 and q[0][0] < monsters[i][0]:
    s -= q[0][1]
    q.popleft()

  h = monsters[i][1] - s * A
  if h > 0:
    num_bombs = ceil(h / A)

    q.append((monsters[i][0] + 2 * D, num_bombs))
    s += num_bombs
    ans += num_bombs
    
print(ans)

# Buggy version:
n, d, a = map(int, input().split())
p = []
for i in range(n):
    x, h = map(int, input().split())
    p.append((x, h))

from collections import deque

p.sort()

q = deque()
total = 0
ans = 0
for i in range(n):
    x, h = p[i][0], p[i][1]
    while q and q[0][0] <= x:
        total -= q[0][1]
        q.popleft()
    h -= total
    if h > 0:
        num = (h+a-1)//a
        ans += num
        damage = num*a
        total += damage
        q.append((x+2*d, damage))

print(ans)

# Fixed version:
n, d, a = map(int, input().split())
p = []
for i in range(n):
    x, h = map(int, input().split())
    p.append((x, h))

from collections import deque

p.sort()

q = deque()
total = 0
ans = 0
for i in range(n):
    x, h = p[i][0], p[i][1]
    while q and q[0][0] < x:
        total -= q[0][1]
        q.popleft()
    h -= total
    if h > 0:
        num = (h+a-1)//a
        ans += num
        damage = num*a
        total += damage
        q.append((x+2*d, damage))

print(ans)

# Buggy version:
from collections import deque
n, d, a = map(int, input().split())
d *= 2

count = 0
damage_total = 0
q = deque([])

for i in range(n):
    x, h = map(int, input().split())
    while len(q) > 0 and q[0][0] < x:
        damage_total -= q[0][1]
        q.popleft()

    h -= damage_total
    if h > 0:
        count_now = (h + a - 1) // a
        count += count_now
        damage_now = a * count_now
        damage_total += damage_now
        q.append([x + d, damage_now])

print(count)

# Fixed version:
from collections import deque
n, d, a = map(int, input().split())
monster = []
for i in range(n):
    monster.append(list(map(int, input().split())))

d *= 2
monster.sort()

count = 0
damage_total = 0
q = deque([])

for i in range(n):
    x = monster[i][0]
    h = monster[i][1]
    while len(q) > 0 and q[0][0] < x:
        damage_total -= q[0][1]
        q.popleft()

    h -= damage_total
    if h > 0:
        count_now = (h + a - 1) // a
        count += count_now
        damage_now = a * count_now
        damage_total += damage_now
        q.append([x + d, damage_now])

print(count)

# Buggy version:
import sys
import math

def main():
    n_d_a = sys.stdin.readline().strip().split(' ')
    n, d, a = [int(s) for s in n_d_a]
    xh = [[]] * n

    for i in range(n):
        x, h = [int(s) for s in sys.stdin.readline().strip().split(' ')]
        xh[i] = [x, h]
    xh.sort()

    cur = 0
    right_indices = [0] * n
    for i in range(n):
        cur = max(cur, i)
        x, h = xh[i]
        right_val = x + d * 2
        while cur < n-1 and xh[cur+1][1] <= right_val:
            cur += 1
        right_indices[i] = cur

    imos = [0] * (n+1)
    ans = 0
    for i in range(n):
        if imos[i] < xh[i][1]:
            need = math.ceil((xh[i][1] - imos[i]) / a)
            print('need', need)
            ans += need
            imos[i] += need * a
            right_idx = right_indices[i]
            imos[right_idx+1] -= need * a
        imos[i+1] += imos[i]
    print(ans)

if __name__ == '__main__':
    main()



# Fixed version:
import sys
import math

def main():
    n_d_a = sys.stdin.readline().strip().split(' ')
    n, d, a = [int(s) for s in n_d_a]
    xh = [[]] * n

    for i in range(n):
        x, h = [int(s) for s in sys.stdin.readline().strip().split(' ')]
        xh[i] = [x, h]
    # n = 3
    # d = 1
    # a = 1
    # xh = [[1, 4], [2, 1], [3, 100]]
    xh.sort()

    cur = 0
    right_indices = [0] * n
    for i in range(n):
        cur = max(cur, i)
        x, h = xh[i]
        right_val = x + d * 2
        while cur < n-1 and xh[cur+1][0] <= right_val:
            cur += 1
        right_indices[i] = cur

    imos = [0] * (n+1)
    ans = 0
    for i in range(n):
        if imos[i] < xh[i][1]:
            need = math.ceil((xh[i][1] - imos[i]) / a)
            ans += need
            imos[i] += need * a
            right_idx = right_indices[i]
            imos[right_idx+1] -= need * a
        imos[i+1] += imos[i]
    print(ans)

if __name__ == '__main__':
    main()

# Buggy version:
# input = sys.stdin.readline
from bisect import *
from collections import *
from heapq import *
# import functools
# import itertools
# import math
N,D,A=map(int,input().split())
XH=[list(map(int,input().split())) for i in range(N)]
XH=sorted(XH,key=lambda x:x[0])

lst=[]
bomb=[]
count=0
nowbomb=0
idx=0
#print(XH)
for x,h in XH:
    print(lst,bomb)
    if lst:
        while idx<len(lst) and lst[idx]<x-D:
            nowbomb-=bomb[idx]
            idx+=1
    a=h-nowbomb
    if a>0:

        b=a//A
        #print(b)
        nowbomb+=D*b
        count+=b
        lst.append(x+D)
        bomb.append(b*D)

print(count)


# Fixed version:
# input = sys.stdin.readline
from bisect import *
from collections import *
from heapq import *
# import functools
# import itertools
# import math
N,D,A=map(int,input().split())
XH=[list(map(int,input().split())) for i in range(N)]
XH=sorted(XH,key=lambda x:x[0])

lst=[]
bomb=[]
count=0
nowbomb=0
idx=0
#print(XH)
for x,h in XH:
    #print(lst,bomb)
    if lst:
        while idx<len(lst) and lst[idx]<x-D:
            nowbomb-=bomb[idx]
            idx+=1
    #print(nowbomb)
    a=h-nowbomb
    if a>0:

        b=a//A+(a%A>0)*1
        #print(a,b)
        nowbomb+=b*A
        count+=b
        lst.append(x+D)
        bomb.append(b*A)

print(count)

# Buggy version:
n,d,a=map(int,input().split())
xh=[list(map(int,input().split())) for _ in range(n)]
xh.sort(key=itemgetter(0))

import collections
pq=collections.deque()

ans = 0
totalDamage = 0


for i in range(n):
    x,h = xh[i]
    if len(pq) and pq[0][0] < x:
        totalDamage -= pq[0][1]
        pq.popleft()
    h -=totalDamage
    if h <= 0:
        continue
    num = (h + a -1) //a
    ans += num
    dam = num*a
    totalDamage += dam
    pq.append((x+2*d,dam))

print(ans)

# Fixed version:
n,d,a=map(int,input().split())
xh=[list(map(int,input().split())) for _ in range(n)]
xh.sort()

import collections
pq=collections.deque()

ans = 0
totalDamage = 0


for i in range(n):
    x,h = xh[i]
    while len(pq) > 0 and pq[0][0] < x:
        totalDamage -= pq[0][1]
        pq.popleft()
    h -=totalDamage
    if h <= 0:
        continue
    num = (h + a -1) //a
    ans += num
    dam = num*a
    totalDamage += dam
    pq.append((x+2*d,dam))

print(ans)

# Buggy version:
from collections import deque
import math
n, d, a = map(int, input().split())
data = []
for i in range(n):
    data.append(list(map(int, input().split())))
data.sort()
dam = 0
ans = 0
q = deque()
for i in range(n):
    x,h = data[i]
    while q:
        k = q.popleft()
        if k[1] >= x:
            q.appendleft(k)
            break
        else:
            dam -= k[0]
    print(q)
    h -= dam
    h = max(h, 0)
    count = math.ceil(h / a)
    dam += count * a
    q.append([count * a, x + 2*d])
    ans += count
print(ans)



# Fixed version:
from collections import deque
import math
n, d, a = map(int, input().split())
data = []
for i in range(n):
    data.append(list(map(int, input().split())))
data.sort()
dam = 0
ans = 0
q = deque()
for i in range(n):
    x,h = data[i]
    while q:
        k = q.popleft()
        if k[1] >= x:
            q.appendleft(k)
            break
        else:
            dam -= k[0]
    h -= dam
    h = max(h, 0)
    count = math.ceil(h / a)
    dam += count * a
    q.append([count * a, x + 2*d])
    ans += count
print(ans)

# Buggy version:
import sys
n, D, a = map(int, input().split())
tg = []
for _ in range(n):
    x, h = map(int, sys.stdin.readline().split())
    c = h // a
    if h % a > 0:
        c+=1
    tg.append([x, c])

class BIT:
    def __init__(self, n):
        self.n = n
        self.N = 1 << n.bit_length()
        self.data = [0] * (self.N +1)

    def add(self, i, x):
        while i <= self.N:
            self.data[i] += x
            i += i & -i

    def sum(self, i):
        total = 0
        while i > 0:
            total += self.data[i]
            i -= i&-i
        return total

    def search(self, w):
        if w <= 0:
            return 0
        x = 0
        k = self.N >> 1
        while k > 0:
            if x+k <= self.N and self.data[x+k] < w:
                w -= self.data[x+k]
                x += k
            k = k >> 1
        return x+1

    def len(self):
        return self.data[self.N]

tg = sorted(tg, key=lambda x:x[0])
bit = BIT(n+2)
result = 0
ind = 0
for i in range(n):
    c = tg[i][1] - bit.sum(i+1)
    d = tg[i][0]
    if c <= 0:
        continue
    result += c
    wd = d + 2*D
    if ind < c:
        ind = c
    for j in range(ind, n):
        if tg[j][0] <= wd:
            ind = j
        else:
            break
    bit.add(d+1, c)
    bit.add(ind+2, -c)
print(result)

# Fixed version:
import sys
n, D, a = map(int, input().split())
tg = []
for _ in range(n):
    x, h = map(int, sys.stdin.readline().split())
    c = h // a
    if h % a > 0:
        c+=1
    tg.append([x, c])

class BIT:
    def __init__(self, n):
        self.n = n
        self.N = 1 << n.bit_length()
        self.data = [0] * (self.N +1)

    def add(self, i, x):
        while i <= self.N:
            self.data[i] += x
            i += i & -i

    def sum(self, i):
        total = 0
        while i > 0:
            total += self.data[i]
            i -= i&-i
        return total

    def search(self, w):
        if w <= 0:
            return 0
        x = 0
        k = self.N >> 1
        while k > 0:
            if x+k <= self.N and self.data[x+k] < w:
                w -= self.data[x+k]
                x += k
            k = k >> 1
        return x+1

    def len(self):
        return self.data[self.N]

tg = sorted(tg, key=lambda x:x[0])
bit = BIT(n+2)
result = 0
ind = 0
for i in range(n):
    c = tg[i][1] - bit.sum(i+1)
    d = tg[i][0]
    if c <= 0:
        continue
    result += c
    wd = d + 2*D
    if ind < i:
        ind = i
    for j in range(ind, n):
        if tg[j][0] <= wd:
            ind = j
        else:
            break
    bit.add(i+1, c)
    bit.add(ind+2, -c)
print(result)

# Buggy version:
import collections
import bisect
import sys
input = sys.stdin.readline

# mod = 998244353
# mod = 1000000007

n, d, a = [ int(v) for v in input().split() ]
monster = []
for _ in range(n):
    x, h = [ int(v) for v in input().split() ]
    monster.append([x, h])
monster.sort()


monster_x, monster_h = [], []
for x, h in monster:
    monster_x.append(x)
    monster_h.append(h)
    


deq = collections.deque([])
totaldamage = 0
ans = 0

for i in range(n):
    monster_h[i] -= totaldamage


    stop = 1
    while stop == 0 and len(deq) > 0:

        if deq[-1][0] == i:
            totaldamage -= deq[-1][1]
            deq.pop()
        else:
            stop = 0

    if monster_h[i] > 0:
        index = bisect.bisect_left(monster_x, monster_x[i]+2*d)
        deq.appendleft([index, monster_h[i]])
        f = (monster_h[i] + a - 1) // a
        ans += f 
        totaldamage += f* a
        monster_h[i] = 0



print(ans)

# Fixed version:
import collections
import bisect
import sys
input = sys.stdin.readline

# mod = 998244353
# mod = 1000000007

n, d, a = [ int(v) for v in input().split() ]
monster = []
for _ in range(n):
    x, h = [ int(v) for v in input().split() ]
    monster.append([x, h])
monster.sort()


monster_x, monster_h = [], []
for x, h in monster:
    monster_x.append(x)
    monster_h.append(h)
    

deq = collections.deque([])
totaldamage = 0
ans = 0

for i in range(n):
    
    stop = 1
    while stop == 1 and len(deq) > 0:
        if deq[-1][0] < monster_x[i]:
            totaldamage -= deq[-1][1]
            deq.pop()
        else:
            stop = 0
    
    monster_h[i] -= totaldamage
    if monster_h[i] > 0:
        index = monster_x[i] + 2*d
        
        f = (monster_h[i] + a - 1) // a
        ans += f 
        totaldamage += f * a
        deq.appendleft([index, f*a])
        monster_h[i] = 0

print(ans)

# Buggy version:
N,D,A = map(int, input().split())
L = [[int(l) for l in input().split()] for _ in range(N)]

class Bit:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
 
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

bit = Bit(N)
L.sort()
X = []
for i in range(N):
    X.append(L[i][0])

import bisect
ans = 0
for i in range(N):
    L[i][1] -= bit.sum(N)-bit.sum(i)
    if L[i][1] <= 0:
        continue
    num = L[i][1]//A+min(1, L[i][1]%A)
    ans += num
    j = bisect.bisect_right(X, L[i][0]+2*D)
    j -= 1
    if j > i:
        bit.add(i+1, num*A)
    
print(ans)

# Fixed version:
N,D,A = map(int, input().split())
L = [[int(l) for l in input().split()] for _ in range(N)]

class Bit:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
 
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

bit = Bit(N)
L.sort()
X = []
for i in range(N):
    X.append(L[i][0])

import bisect
ans = 0
for i in range(N):
    L[i][1] -= bit.sum(N)-bit.sum(i)
    if L[i][1] <= 0:
        continue
    num = L[i][1]//A+min(1, L[i][1]%A)
    ans += num
    j = bisect.bisect_right(X, L[i][0]+2*D)
    if j > i:
        bit.add(j, num*A)
    
print(ans)

# Buggy version:
#  --*-coding:utf-8-*--

import math

N,D,A = map(int, input().split())
XH = sorted(tuple(map(int, input().split())) for _ in range(N))

Q = []
qIdx = 0
s = 0
t = 0

for (x, h) in XH:
    while qIdx < len(Q) and  Q[qIdx][0] < x:
        s -= Q[qIdx][1]
        qIdx += 1

    if s < h:
        q = int(math.ceil((h-s)/A))
        Q.append((x+2*D, q))
        s += q
        t += q

print(t)
        
        


# Fixed version:
#  --*-coding:utf-8-*--

import math

N,D,A = map(int, input().split())
XH = sorted(tuple(map(int, input().split())) for _ in range(N))

Q = []
qIdx = 0
s = 0
t = 0

for (x, h) in XH:
    while qIdx < len(Q) and  Q[qIdx][0] < x:
        s -= Q[qIdx][1]
        qIdx += 1

    if s < h:
        q = int(math.ceil((h-s)/A))
        Q.append((x+2*D, q*A))
        s += q*A
        t += q

print(t)

# Buggy version:
from bisect import bisect_left as bl
n,d,a=map(int,input().split())
s=sorted([list(map(int,input().split()))for i in range(n)])
c=0
p=[0]
q=[0]
for i in range(n):
    a=bl(q,s[i][0])
    s[i][1]-=p[-1]-p[a-1]
    if s[i][1]>0:
        t=((s[i][1]-1)//a+1)
        c+=t
        p.append(p[-1]+t)
        q.append(s[i][0]+2*d)
print(c)

# Fixed version:
from bisect import bisect_left as bl
n,d,a=map(int,input().split())
s=sorted([list(map(int,input().split()))for i in range(n)])
c=0
p=[0]
q=[0]
for i in range(n):
    g=bl(q,s[i][0])
    s[i][1]-=a*(p[-1]-p[g-1])
    if s[i][1]>0:
        t=((s[i][1]-1)//a+1)
        c+=t
        p.append(p[-1]+t)
        q.append(s[i][0]+2*d)
print(c)

# Buggy version:
from math import ceil
from bisect import bisect
from operator import itemgetter
class BIT:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)

    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s

    def add(self, i, x):
        i += 1
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

N,D,A = map(int,input().split())
XH = [list(map(int,input().split())) for _ in range(N)]
XH.sort(key=itemgetter(0))
X = [XH[i][0] for i in range(N)]
H = [XH[i][1] for i in range(N)]

bit = BIT(N)

ans = 0
for i in range(N):
    bit.add(i+1,H[i])
    bit.add(i+2,-H[i])
    h = bit.sum(i+1)
    if h>0:
        ans += ceil(h/A)
        x = -ceil(h/A)*A
        j = bisect(X,X[i]+2*D)
        bit.add(i+1,x)
        bit.add(j+1,-x)

print(ans)

# Fixed version:
from math import ceil
from bisect import bisect
from operator import itemgetter
class BIT:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
 
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

N,D,A = map(int,input().split())
XH = [list(map(int,input().split())) for _ in range(N)]
XH.sort(key=itemgetter(0))
X = [XH[i][0] for i in range(N)]
H = [XH[i][1] for i in range(N)]

bit = BIT(N)
ans = 0
for i in range(N):
    bit.add(i+1,H[i])
    bit.add(i+2,-H[i])
    h = bit.sum(i+1)
    if h>0:
        ans += ceil(h/A)
        x = -ceil(h/A)*A
        j = bisect(X,X[i]+2*D)
        bit.add(i+1,x)
        bit.add(j+1,-x)

print(ans)

# Buggy version:
N, D, A = map(int, input().split())
XH = [[0, 0] for _ in range(N)]

for i in range(N):
    XH[i][0], XH[i][1] = map(int, input().split())

XH.sort()
# XH

ans = 0
P = 0
hist = []
j = 0
for i in range(N):
    X, H = XH[i]
    while True:
        if j >= len(hist):
            break
        if hist[j][0] >= 0:
            break
        if hist[j][0] < X:
            P -= hist[0][1]
            j += 1
    
    if H - P > 0:
        if (H - P) % A == 0:
            bomb = (H - P) // A
        else:
            bomb = (H - P) // A + 1
        ans += bomb
        P += bomb * A
        hist.append((X + 2 * D, bomb * A))
    

print(ans)

# Fixed version:
N, D, A = map(int, input().split())
XH = [[0, 0] for _ in range(N)]

for i in range(N):
    XH[i][0], XH[i][1] = map(int, input().split())

XH.sort()
# XH

ans = 0
P = 0
hist = []
j = 0
for i in range(N):
    X, H = XH[i]
    while True:
        if j >= len(hist):
            break
        if hist[j][0] >= X:
            break
        if hist[j][0] < X:
            P -= hist[j][1]
            j += 1
    
    if H - P > 0:
        if (H - P) % A == 0:
            bomb = (H - P) // A
        else:
            bomb = (H - P) // A + 1
        ans += bomb
        P += bomb * A
        hist.append((X + 2 * D, bomb * A))
    

print(ans)

# Buggy version:
# -*- coding: utf-8 -*-
import heapq
from math import ceil
n,d,a = map(int, input().split())
xh = [list(map(int, input().split())) for _ in range(n)]
xh.sort()
print(xh)
res = 0
b = []
heapq.heapify(b)
r = 0
for i in range(n):
    x,h = xh[i]

    j = 0
    while len(b)>0 and b[j][0]<=x:
        r += b[j][1]
        heapq.heappop(b)
    c = ceil((h-r)/a)
    res += c
    r += c*a
    
    if c>0:
        heapq.heappush(b, (x+2*d+1, -c*a))

print(res)

# Fixed version:
# -*- coding: utf-8 -*-
import heapq
from math import ceil
n,d,a = map(int, input().split())
xh = [list(map(int, input().split())) for _ in range(n)]
xh.sort()

res = 0
b = []
heapq.heapify(b)
r = 0
for i in range(n):
    x,h = xh[i]

    while len(b)>0 and b[0][0]<=x:
        r += b[0][1]
        heapq.heappop(b)
    c = max(ceil((h-r)/a), 0)
    res += c
    r += c*a
    
    if c>0:
        heapq.heappush(b, (x+2*d+1, -c*a))

print(res)