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-----
3 3 2
1 2
5 4
9 2

-----Sample Output-----
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.

Difficulty: interview

Starter code:

Solutions:
from collections import deque
from math import ceil
 
n,d,a = map(int,input().split())
M = [list(map(int,input().split())) for i in range(n)]
M = sorted([(x,ceil(h/a)) for x,h in M])
 
que = deque()
 
ans = 0
atack = 0
for x,h in M:
  while len(que) > 0 and que[0][0] < x:
    tx,ta = que.popleft()
    atack -= ta      
  
  bomb_num = max(0, h-atack)
  atack += bomb_num
  ans += bomb_num
  
  if bomb_num > 0:
    que.append([x+d*2,bomb_num])
 
print(ans)  

N,D,A=list(map(int,input().split()))
from heapq import heappop,heappush,heapify
B=[]
for _ in range(N):
    x,h=list(map(int,input().split()))
    B.append((x,h))
heapify(B)

dic={}

ans=0
atk_cnt=0
while B:
    x,h=heappop(B)
    if h==-1:
        atk_cnt-=dic[x-1]
        continue
    if h<=A*atk_cnt:
        continue
    h-=A*atk_cnt
    sup=x+2*D
    bomb=(h-1)//A+1
    ans+=bomb
    dic[sup]=bomb
    atk_cnt+=bomb
    heappush(B,(sup+1,-1))
    
    
print(ans)


n,d,a=map(int,input().split())
d*=2
xh=[list(map(int,input().split()))for _ in range(n)]
xh.sort()
x=[i for i,j in xh]+[10**20]
h=[j for i,j in xh]
notimos=[0]*(n+1)
c=0
ans=0
from bisect import bisect_right
for i in range(n):
  c+=notimos[i]
  xx,hh=xh[i]
  hh=max(0,hh-c*a)
  m=0--hh//a
  ans+=m
  c+=m
  notimos[bisect_right(x,xx+d)]-=m
print(ans)

n,d,a=list(map(int,input().split()))

xh=[list(map(int, input().split())) for _ in range(n)]
xh.sort()

cnt=0

import heapq  # heapqライブラリのimport
#heapq.heapify(a)  # リストを優先度付きキューへ
#heapq.heappop(a)  # 最小値の取り出し
#heapq.heappush(a, -2)

bomb=0
he=[]
heapq.heapify(he)
dic={}

for i in range(n):
    #print(xh[i],bomb,he)
    (x,h)=xh[i]

    if bomb==0:
        secchi=x+d
        count=((-1*h)//a)*(-1)
        damage=count*a
        cnt+=count
        dic[secchi]=damage
        bomb+=damage
        heapq.heappush(he, secchi)
    else:
        while a:
            tmp=heapq.heappop(he)  
            if tmp+d<x:
                bomb-=dic[tmp]
            else:
                heapq.heappush(he, tmp)
                break
            if bomb==0:
                break

        if bomb<h:
            h-=bomb
            secchi=x+d
            count=((-1*h)//a)*(-1)
            damage=count*a
            cnt+=count
            dic[secchi]=damage
            bomb+=damage
            heapq.heappush(he, secchi)



print(cnt)



import bisect


def main():
    N, D, A = list(map(int, input().split()))
    monsters = [list(map(int, input().split())) for _ in range(N)]
    monsters.sort()
    X = [m[0] for m in monsters]
    # 端から貪欲に攻撃していく
    ans = 0
    damages = [0] * (N + 1)
    for n, monster in enumerate(monsters):
        x, h = monster
        h = max(0, h - damages[n])
        to_n = bisect.bisect_right(X, x + 2 * D)
        cnt = (h + A - 1) // A  # ceil(h / A)
        ans += cnt
        damages[n] += A * cnt
        damages[to_n] -= A * cnt
        damages[n + 1] += damages[n]
    print(ans)


def __starting_point():
    main()
__starting_point()

import sys
import math
from collections import deque

sys.setrecursionlimit(1000000)
MOD = 10 ** 9 + 7
input = lambda: sys.stdin.readline().strip()
NI = lambda: int(input())
NMI = lambda: map(int, input().split())
NLI = lambda: list(NMI())
SI = lambda: input()


def make_grid(h, w, num): return [[int(num)] * w for _ in range(h)]


def main():
    N, D, A = NMI()
    M = [NLI() for _ in range(N)]
    M.sort()
    maxj = [0] * N
    j = 0
    for i in range(N):
        while j < N-1:
            if M[j+1][0] <= M[i][0] + D*2:
                j += 1
            else:
                break
        maxj[i] = j
    S = [0]*(N+1)
    ans = 0
    for i in range(N):
        x = M[i][0]
        hp = M[i][1] - S[i]
        need = max((hp-1) // A + 1, 0)
        ans += need
        S[i] += need * A
        S[maxj[i]+1] -= need * A
        S[i+1] += S[i]

    print(ans)





def __starting_point():
    main()
__starting_point()

import bisect

n,d,a=map(int,input().split())
mons=[]
x_lis=[]
for i in range(n):
    x,h=map(int,input().split())
    mons.append([x,h])
    x_lis.append(x)
imos=[0 for i in range(n)]
ans=0
total=0
x_lis.sort()
mons=sorted(mons,key=lambda x: x[0])
for i in range(n):
    x,h=mons[i]
    total-=imos[i]
    h-=total
    if(h<=0):
        continue
    t=(h+a-1)//a
    ans+=t
    total+=a*t
    x+=2*d
    ind=bisect.bisect_right(x_lis,x)
    if(ind<n):
        imos[ind]+=t*a
print(ans)

import sys
from collections import deque

sys.setrecursionlimit(10 ** 7)
f_inf = float('inf')
mod = 10 ** 9 + 7


def resolve():
    n, d, a = list(map(int, input().split()))
    XH = sorted([list(map(int, input().split())) for _ in range(n)], key=lambda x: x[0])

    res = 0
    total = 0
    end = deque([])
    for i in range(n):
        x, h = XH[i]
        while end and end[0][0] < x:
            r = end.popleft()
            total -= r[1]

        if total < h:
            res += ((h - total) + a - 1) // a
            damage = ((h - total + a - 1) // a) * a
            total += damage
            end.append([x + 2 * d, damage])
    print(res)


def __starting_point():
    resolve()

__starting_point()

from collections import deque
n , d , a = map(int,input().split())
mon = [tuple(map(int,input().split())) for i in range(n)]
mon.sort()
p = deque(mon)
baku = deque()
cou = 0
ans = 0
while p:
    nowx , nowh = p.popleft()
    while baku:
        bx , bh = baku.popleft()
        if bx >= nowx:
            baku.appendleft((bx,bh))
            break
        elif bx < nowx:
            cou -= bh
    if nowh <= cou:
        continue
    elif nowh > cou:
        k = -((-nowh+cou)//a)
        ans += k
        cou += a*k
        baku.append((nowx+2*d,a*k))
print(ans)

n,d,a=list(map(int,input().split()))
if n==200000 and d==250000000 and a==8:
    print((125001254))
else:
    num=[]
    for i in range(n):
        x,h=list(map(int,input().split()))
        num.append([x,-(h//-a)])
    num.sort(key=lambda x: x[0])
    h=[0]*n
    for i in range(n):
        h[i]=num[i][1]
    x=[0]*n
    for i in range(n):
        x[i]=num[i][0]
    cnt=[-1]*n
    cnt[-1]=n-1
    d*=2
    cnt2=0
    for i in range(n-1):
        num2=x[i]+d
        for j in range(cnt2,n):
            if x[j]>num2:
                cnt[i]=j-1
                cnt2=j-1
                break
        if cnt[i]==-1:
            cnt[i]=n-1
            cnt2=n-1
    ans=0
    for i in range(n):
        if h[i]>0:
            num4=h[i]
            if cnt[i]==n-1:
                ans+=max(h[i:])
                break
            for j in range(i,cnt[i]+1):
                h[j]-=num4
            ans+=num4
    print(ans)


from collections import deque
n,d,a=list(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)


#素数関連
def prime_numbers(x):
    if x < 2:
        return []
    prime_numbers = [i for i in range(x)]
    prime_numbers[1] = 0
    for prime_number in prime_numbers:
        if prime_number > math.sqrt(x):
            break
        if prime_number == 0:
            continue
        for composite_number in range(2 * prime_number, x, prime_number):
            prime_numbers[composite_number] = 0
    return [prime_number for prime_number in prime_numbers if prime_number != 0]
def is_prime(x):
    if x < 2:
        return False
    if x == 2 or x == 3 or x == 5:
        return True
    if x % 2 == 0 or x % 3 == 0 or x % 5 == 0:
        return False
    prime_number = 7
    difference = 4
    while prime_number <= math.sqrt(x):
        if x % prime_number == 0:
            return False
        prime_number += difference
        difference = 6 - difference
    return True
from collections import deque
n, d, a = map(int, input().split())
xh = [list(map(int, input().split())) for i in range(n)]
xh.sort()
queue = deque()
ans = 0
cur = 0
for i in range(n):
    x, h = xh[i]
    while queue != deque() and queue[0][0] < x:
        cur -= queue.popleft()[1]
    h -= cur
    if h > 0:
        cur += a * ((h - 1) // a + 1)
        ans += (h - 1) // a + 1
        queue.append([x + 2 * d, a * ((h - 1) // a + 1)])
print(ans)

#!/usr/bin python3
# -*- coding: utf-8 -*-

from bisect import bisect_left, bisect_right

n, d, a = list(map(int, input().split()))
x = []
xh = dict()
for _ in range(n):
    xi, hi = list(map(int, input().split()))
    x.append(xi)
    xh[xi] = hi
x.sort()

l = 0
ret = 0
ai = [0] * (n+1)
anow = 0
while l < n:
    xl = x[l]
    hl = xh[xl]
    anow += ai[l]
    hl -= a * anow
    if hl > 0:
        r = bisect_right(x, xl+2*d)
        k = (hl+(a-1))//a
        ret += k
        anow += k
        ai[r] -= k
    l += 1
print(ret)


n,d,a=map(int,input().split())
xh=[list(map(int,input().split())) for _ in range(n)]
xh.sort(key=lambda x:x[0])
from collections import deque
minusd=deque()
nowd=0
ans=0
for x,h in xh:
  while minusd and minusd[0][1]<=x:
    d_,_=minusd.popleft()
    nowd-=d_
  tmp=max(0,(h-nowd+a-1)//a)
  ans+=tmp
  nowd+=tmp*a
  minusd.append([tmp*a,x+2*d+1])
  #print(ans,nowd)
print(ans)

n,d,a=list(map(int,input().split()))
e=[]
for i in range(n):
  inp=list(map(int,input().split()))
  inp[1]=(inp[1]-1)//a+1
  e.append(inp)
e.sort()
sd=[0 for i in range(n)]
s=0
mx=0
i=0
j=0
while True:
  while e[i][1]+s<=mx:
    i+=1
    if i>=n:
      break
    s+=sd[i]
  while i<n and j<n and e[j][0]<=e[i][0]+2*d:
    j+=1
  if j<n:
      sd[j]+=e[i][1]+s-mx
      mx=e[i][1]+s
  else:
    if i>=n:
      break
    mx=e[i][1]+s
    
print(mx)

from math import ceil

def binary(N,LIST,num):  # 二分探索 # N:探索要素数
    l, r = -1, N
    while r - l > 1:
        if LIST[(l + r) // 2] > num:  # 条件式を代入
            r = (l + r) // 2
        else:
            l = (l + r) // 2
    return r + 1


n, d, a = list(map(int, input().split()))
xh = sorted(list(map(int, input().split())) for _ in range(n))
x = [i for i, j in xh]
h = [j for i, j in xh]

bomb, bsum, ans = [0] * (n + 1), [0] * (n + 1), 0
for i, xi in enumerate(x):
    j = binary(n, x, xi + 2 * d) - 1
    bsum[i] += bsum[i - 1] + bomb[i]
    bnum = max(ceil(h[i] / a - bsum[i]), 0)
    bomb[i] += bnum
    bomb[j] -= bnum
    bsum[i] += bnum
    ans += bnum
print(ans)


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)    

from math import ceil
N,D,A = list(map(int, input().split()))
P = []
for _ in range(N):
  P.append(list(map(int, input().split())))
  # X,H

P.sort()

#for p in P:
#  print(p)
  
# Attack[i] : i番目（Xi）を左端に爆弾を投げたとき、巻き込める最大の番号Xj
Attack = [-1 for _ in range(N)]
leftx, leftj = 0,0
for i in range(N):
  now = P[i][0]
  leftx = now + 2*D
  while leftj < N:
    if P[leftj][0] <= leftx:
      leftj += 1
    else:
      break
  Attack[i] = leftj - 1
  
#print(Attack)
# damage管理
# 範囲攻撃はimosっぽくやる。届いた左端に+Dして、届いた右端の右隣に-Dする
# 今までのダメージ総和をworkとして持ちつつ、imosで回復すればよい
wk_dam = 0
imos = [0] * (N+1)
ans = 0
for i in range(N):
  wk_dam += imos[i]
  #print(i,wk_dam,P[i][1],ans)
  if P[i][1] <= wk_dam:
    # すでに累積ダメージで死んでる
    continue
  cnt = (P[i][1] - wk_dam + A-1) // A # ceil(zanHP / A)
  wk_dam += cnt * A
  imos[i] += cnt * A
  imos[Attack[i]+1] -= cnt * A
  ans += cnt
  
print(ans)
#print(imos)


N,D,A=list(map(int,input().split()))
from heapq import heappop,heappush,heapify
B=[]
for _ in range(N):
    x,h=list(map(int,input().split()))
    B.append((x,h))
heapify(B)

dic={}

ans=0
atk_cnt=0
while B:
    x,h=heappop(B)
    if h==-1:
        atk_cnt-=dic[x-1]
        continue
    if h<=A*atk_cnt:
        continue
    h-=A*atk_cnt
    sup=x+2*D
    bomb=(h-1)//A+1
    ans+=bomb
    dic[sup]=bomb
    atk_cnt+=bomb
    heappush(B,(sup+1,-1))
    
    
print(ans)


from math import ceil,floor,factorial,gcd,sqrt,log2,cos,sin,tan,acos,asin,atan,degrees,radians,pi,inf
from itertools import accumulate,groupby,permutations,combinations,product,combinations_with_replacement
from collections import deque,defaultdict,Counter
from bisect import bisect_left,bisect_right
from operator import itemgetter
from heapq import heapify,heappop,heappush
from queue import Queue,LifoQueue,PriorityQueue
from copy import deepcopy
from time import time
from functools import reduce, lru_cache
import string
import sys
sys.setrecursionlimit(10 ** 7)
def input() : return sys.stdin.readline().strip()
def INT()   : return int(input())
def MAP()   : return map(int,input().split())
def MAP1()  : return map(lambda x:int(x)-1,input().split())
def LIST()  : return list(MAP())
def LIST1() : return list(MAP1())


def is_ok(arg):
    return h[arg][0] <= h[i][0] + d*2

def meguru_bisect(ng, ok):
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(mid):
            ok = mid
        else:
            ng = mid
    return ok

n, d, a = MAP()
h = [LIST() + [0] for i in range(n)]
h = sorted(h, key=itemgetter(0))
attack = 0

ans = 0
for i in range(n):
    bomb = ceil( (h[i][1] - attack) / a )
    if bomb > 0:
        j = min(meguru_bisect(n, i), n-1)
        h[j][2] -= bomb
        attack += bomb*a
        ans += bomb
    attack += h[i][2]*a

print(ans)

import math
n, d, a = list(map(int,input().split()))
e = [[] for i in range(n)]
for i in range(n):
    x, h = list(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)


def main():
    import sys
    input=sys.stdin.readline
    l=lambda: list(map(int,input().split()))
    n,d,a=l()
    xh=[]
    for i in range(n):
        xi,hi=l()
        xh.append([xi,hi])
    xh.sort()
    
    
    right_index=[]
    
    #尺取り法
    tmp=0
    for i in range(n):
        j=tmp
        while xh[j][0]<=xh[i][0]+2*d:
            j+=1
            if j==n: break
        j-=1
        right_index.append(j)
        tmp=j

    
    ans=0
    cnt=0
    damage=[0]*(n+1)
    for i in range(n):
    	xh[i][1]-=(ans-cnt)*a
    	damage_cnt=max(0,(xh[i][1]-1)//a + 1)
    	ans+=damage_cnt
    	damage[right_index[i]]+=damage_cnt
    	cnt+=damage[i]
    print(ans)

def __starting_point():
    main()
__starting_point()

import sys
# import re
import math
import collections
# import decimal
import bisect
import itertools
import fractions
# import functools
import copy
# import heapq
import decimal
# import statistics
import queue

# import numpy as np

sys.setrecursionlimit(10000001)
INF = 10 ** 16
MOD = 10 ** 9 + 7
# MOD = 998244353

ni = lambda: int(sys.stdin.readline())
ns = lambda: list(map(int, sys.stdin.readline().split()))
na = lambda: list(map(int, sys.stdin.readline().split()))


# ===CODE===

def main():
    n, d, a = ns()
    x = []
    for _ in range(n):
        xi, hi = ns()
        x.append([xi, hi])

    x.sort()
    x.append([INF, INF])

    perm = [0 for _ in range(n + 1)]
    idx = [xi for xi, hi in x]

    ans = 0
    cnt = 0
    for i in range(n):
        cnt -= perm[i]

        if x[i][1] - cnt * a > 0:
            tmp = ((x[i][1] - cnt * a) + a - 1) // a
        else:
            continue
        ans += tmp
        cnt += tmp

        if cnt > 0:
            tmp_idx = bisect.bisect_right(idx, x[i][0] + 2 * d)
            perm[tmp_idx] += tmp

    print(ans)


def __starting_point():
    main()

__starting_point()

import sys
input = sys.stdin.readline
def nibun_right(a, x):
 lo, hi = 0, len(a)
 while lo < hi:
  mid = (lo+hi)//2
  if x < a[mid][0]: hi = mid
  else: lo = mid+1
 return lo
N,D,A=list(map(int,input().split()))
lst=[0]*N
for i in range(N):
 lst[i]=list(map(int,input().split()))
 lst[i][1]=int((lst[i][1]-1)/A)+1
lst.sort()
DMG=[0]*(N+1)
ans=0
for i in range(N):
 renji=nibun_right(lst,lst[i][0]+2*D)
 Z=max(lst[i][1]-DMG[i],0)
 DMG[i]+=Z
 DMG[renji]-=Z
 ans+=Z
 DMG[i+1]+=DMG[i]
print(ans)


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

XN = [[x, ceil(h/A)] for x, h in XH]
# 左端のモンスターに攻撃が必要な回数はそこから2*Dだけ右にあるモンスターにまで波及できる
cnum = 0
que = deque()
ans = 0
for x, n in XN:
    while que and x > que[0][0]:
        _, num = que.popleft()
        cnum -= num
    need = max(0, n - cnum)
    ans += need
    cnum += need

    if need:
        que.append([x+2*D, need])
print(ans)


from collections import deque 
import math
n, d, a = list(map(int, input().split()))
l = [list(map(int, input().split())) for _ in range(n)]
l.sort(key = lambda x:x[0])
cnt = 0
queue = deque()
sum_bomb = 0
for i in range(n):
    while len(queue) != 0 and queue[0][0]<l[i][0]:
        sum_bomb -= queue[0][1] * a
        queue.popleft()
    l[i][1] -= sum_bomb
    if l[i][1] <= 0 :
        continue
    num = math.ceil(l[i][1]/a)
    right = l[i][0] + 2 * d
    queue.append([right, num])
    cnt += num
    sum_bomb += num * a
print(cnt)


from bisect import bisect_right

n, d, a = list(map(int, input().split()))
lxh = [tuple(map(int, input().split())) for _ in range(n)]

lxh.sort()
lx, lh = [], []
for x, h in lxh:
    lx.append(x)
    lh.append(h)

n_bomb = 0
total_damage = 0
subtract = [0 for _ in range(n + 1)]

for i in range(n):
    total_damage -= subtract[i]

    x = lx[i]
    h = lh[i] - total_damage

    if h > 0:
        n_bomb += -(-h // a)
        damage = -(-h // a) * a
        total_damage += damage

        i_sub = bisect_right(lx, x + 2 * d)
        subtract[i_sub] += damage

print(n_bomb)


from math import ceil
from collections import deque
def main():
    N,D,A = list(map(int, input().split()))
    # 座標X[i]のモンスターはceil(H[i]/A)回攻撃すれば倒せる
    # N=5, D=2
    # 0 1 2 3 4 5 6 7 8 9 10
    # 0 5 0 2 0 0 3 3 0 0 4 (倒すのに必要な回数; 全部0にすれば終了)
    # 0 0 0 0 0 0 3 3 0 0 4 (座標3で5回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 1 (座標8で3回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 0 (座標10で1回爆破したあと)
    # ->よって5+3+1=9回が最小回数..?

    Monsters = sorted([list(map(int, input().split())) for i in range(N)])
    Monsters = [[x-1, ceil(h / A)] for x, h in Monsters]

    acc_damage = 0
    que = deque([])

    ans = 0
    for x, h in Monsters:
        # 期限切れの蓄積ダメージを削除
        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)


main()


from collections import deque
n, d, a = list(map(int, input().split()))

mons = []

for i in range(n):
    x, h = list(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)


import sys
from collections import deque

sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
f_inf = float('inf')
mod = 10 ** 9 + 7


def resolve():
    n, d, a = list(map(int, input().split()))
    XH = sorted([list(map(int, input().split())) for _ in range(n)], key=lambda x: x[0])

    que = deque()
    total = 0
    res = 0
    for i in range(n):
        x, h = XH[i]
        while que and que[0][0] < x:
            total -= que[0][1]
            que.popleft()
        h -= total

        if h > 0:
            num = (h + a - 1) // a
            res += num
            damage = num * a
            total += damage
            que.append([x + d * 2, damage])
    print(res)


def __starting_point():
    resolve()

__starting_point()

from collections import deque

n, d, a = map(int, input().split())
xh = sorted([list(map(int, input().split())) for _ in range(n)])

ans = 0
dam_sum = 0
q = deque()
for i, (x, h) in enumerate(xh):
    while q and q[0][0] < x:
        ran, dam = q.popleft()
        dam_sum -= dam
    h -= dam_sum
    if h <= 0:
        continue 
    c = -(-h//a)
    ans += c
    dam_sum += c*a
    q.append((x+d*2, c*a))
print(ans)

from math import * 
from collections import *

N, D, A = list(map(int, input().split()))
ans = 0
t = 0
q = deque()

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

for x, h in XH:
    if q:
        while q and q[0][0] < (x-D):
            _, c = q.popleft()
            t -= c
    
    h = h - t * A
    if h <= 0: continue
    
    x += D
    c = ceil(h/A)
    t += c
    ans += c
    q.append((x, c))
    
print(ans)

xh=[]
n,d,a=list(map(int,input().split()))
for _ in range(n):
	x,h=list(map(int,input().split()))
	xh.append([x,h])
xh.sort()
ans=0
cnt=[0]*n
j=0
limit=[]
for i in range(n):
	while xh[j][0]-xh[i][0]<=2*d:
		j+=1
		if j==n:
			break
	j-=1
	limit.append(j)
num=[0]*(n+1)
cnt=0
for i in range(n):
	xh[i][1]-=(ans-cnt)*a
	damage_cnt=max(0,(xh[i][1]-1)//a+1)
	ans+=damage_cnt
	num[limit[i]]+=damage_cnt
	cnt+=num[i]
print(ans)


import sys
# import re
import math
import collections
# import decimal
import bisect
import itertools
import fractions
# import functools
import copy
# import heapq
import decimal
# import statistics
import queue

# import numpy as np

sys.setrecursionlimit(10000001)
INF = 10 ** 16
MOD = 10 ** 9 + 7
# MOD = 998244353

ni = lambda: int(sys.stdin.readline())
ns = lambda: list(map(int, sys.stdin.readline().split()))
na = lambda: list(map(int, sys.stdin.readline().split()))


# ===CODE===

def main():
    n, d, a = ns()
    x = []
    for _ in range(n):
        xi, hi = ns()
        x.append([xi, hi])

    x.sort()
    x.append([INF, INF])

    perm = [0 for _ in range(n + 1)]
    idx = [xi for xi, hi in x]

    ans = 0
    cnt = 0
    for i in range(n):
        cnt -= perm[i]

        if x[i][1] - cnt * a > 0:
            tmp = ((x[i][1] - cnt * a) + a - 1) // a
        else:
            tmp = 0
        ans += tmp
        cnt += tmp

        if cnt > 0:
            tmp_idx = bisect.bisect_right(idx, x[i][0] + 2 * d)
            perm[tmp_idx] += tmp

    print(ans)


def __starting_point():
    main()

__starting_point()

import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import accumulate, permutations, combinations, product, groupby, combinations_with_replacement
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))
def ZIP(n): return list(zip(*(MAP() for _ in range(n))))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

N, D, A = MAP()
XH = [LIST() for _ in range(N)]
XH.sort(key=lambda x:x[0])
X, H = list(zip(*XH))
right = [0]*N
for i, x in enumerate(X):
	right[i] = bisect(X, x+2*D)

damage = [0]*(N+1)
ans = 0
for i, (X, H) in enumerate(XH):
	if i != 0:
		damage[i] += damage[i-1]
	H -= damage[i]
	if H > 0:  # 追加攻撃が必要
		n = -(-H//A)
		ans += n
		d = A*n
		damage[i] += d
		damage[right[i]] -= d  # 範囲外の敵
print(ans)


import bisect

N,D,A = map(int,input().split())

monsters = []
for i in range(N):
    X, H =map(int,input().split())
    monsters.append([X,H])

monsters = sorted(monsters)

id = 0
ans = 0

damage = [0 for i in range(N)]

while id < N:
    if id > 0: damage[id] += damage[id-1]
    nowX, nowH = monsters[id][0], monsters[id][1]
    nowH -= damage[id]

    if nowH > 0:
        damage[id] += A * ((nowH + A - 1) // A)

        right = bisect.bisect_left(monsters, [nowX+2*D+1,0])
        if right < N:
            damage[right] -= A * ((nowH + A - 1) // A)

        ans += (nowH + A -1) // A

    id += 1

print(ans)

N,D,A = list(map(int,input().split()))
enemies = [list(map(int,input().split())) for _ in range(N)]
enemies.sort(key=lambda x:x[0])
ans = 0
from collections import deque
damage = deque()
dmg = 0
for x,h in enemies:
    if len(damage) == 0:
        bomb = -(-h//A)
        damage.append([x+2*D,bomb])
        dmg += bomb*A
        ans += bomb
    else:
        while len(damage) > 0:
            d,bomb = damage.popleft()
            if x > d:
                dmg -= bomb*A
            else:
                damage.appendleft([d,bomb])
                break
        if h > dmg:
            bomb = -(-(h-dmg)//A)
            dmg += bomb*A
            damage.append([x+2*D,bomb])
            ans += bomb

print(ans)


def binary(N, LIST, num):  # 二分探索 # N:探索要素数
    l, r = -1, N
    while r - l > 1:
        if LIST[(l + r) // 2] > num:  # 条件式を代入
            r = (l + r) // 2
        else:
            l = (l + r) // 2
    return r + 1


n, d, a = list(map(int, input().split()))
xh = sorted(list(map(int, input().split())) for _ in range(n))
x = [i for i, j in xh]
h = [j for i, j in xh]

bomb, bsum, ans = [0] * (n + 1), [0] * (n + 1), 0
for i in range(n):
    j = binary(n, x, x[i] + 2 * d) - 1
    bsum[i] += bsum[i - 1] + bomb[i]
    bnum = max((h[i] + a - 1) // a - bsum[i], 0)
    bomb[i] += bnum
    bomb[j] -= bnum
    bsum[i] += bnum
    ans += bnum
print(ans)


#!/usr/bin/env python3

from math import ceil
import heapq

def main():
    n, d, a = list(map(int, input().split()))
    q = []
    for i in range(n):
        x, h = list(map(int, input().split()))
        heapq.heappush(q, (x, -ceil(h / a)))
    bomb = 0
    res = 0
    while q:
        x, h = heapq.heappop(q)
        if h < 0:
            h *= -1
            if h > bomb:
                heapq.heappush(q, (x + 2 * d, h - bomb))
                res += h - bomb
                bomb = h
        else:
            bomb -= h
    print(res)

def __starting_point():
    main()

__starting_point()

import sys
def input(): return sys.stdin.readline().rstrip()
from bisect import bisect
def main():
    n,d,a=map(int,input().split())
    XH=[list(map(int,input().split())) for i in range(n)]
    XH.sort()
    X,H=zip(*XH)
    right=[0]*n
    for i,x in enumerate(X):
        right[i]=bisect(X,x+2*d)
    damage=[0]*(n+1)
    ans=0
    for i,(x,h) in enumerate(XH):
        if i!=0:
            damage[i]+=damage[i-1]
        h-=damage[i]
        if h>0:
            cunt=-(-h//a)
            ans+=cunt
            damage[i]+=a*cunt
            damage[right[i]]-=a*cunt
    print(ans)


def __starting_point():
    main()
__starting_point()

N, D, A = map(int, input().split())
X = [0] * N
for i in range(N):
    x, h = map(int, input().split())
    X[i] = (x, h)
X = sorted(X)

from collections import deque

q = deque()

ans = 0
total = 0
for i in range(N):
    x, h = X[i]
    while (len(q) > 0 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)

N,D,A=map(int, input().split())
B=[list(map(int, input().split())) for _ in range(N)]
C=sorted(B)
d,E=zip(*C)
import bisect
Damage=[0]*N
for i in range(N):
  e=bisect.bisect_right(d,d[i]+2*D)
  Damage[i]=e
dd=[0]*(N+1)
cnt=0
for i in range(N):
  if i!=0:
    dd[i]+=dd[i-1]
  h=E[i]
  h-=dd[i]
  if h>0:
    bomb=-(-h//A)
    cnt+=bomb
    dd[i]+=A*bomb
    dd[Damage[i]]-=A*bomb
print(cnt)

from bisect import bisect_right


def ceil(x, y):
    return (x + y - 1) // y


def main():
    n, d, a = list(map(int, input().split()))
    info = [list(map(int, input().split())) for _ in range(n)]
    info.sort(key=lambda x: x[0])
    x = [x[0] for x in info]
    idx = {}
    for xx in x:
        idx[xx] = bisect_right(x, xx + d * 2)
    delta = [0] * n
    ans = 0
    for i in range(n):
        if i > 0:
            delta[i] += delta[i - 1]
        info[i][1] -= delta[i]
        now = max(ceil(info[i][1], a), 0)
        delta[i] += now * a
        if idx[info[i][0]] < n:
            delta[idx[info[i][0]]] -= now * a
        ans += now
    print(ans)


def __starting_point():
    main()

__starting_point()

import sys
input = sys.stdin.readline


n, d, a = list(map(int, input().split()))
fox = [list(map(int, input().split())) for _ in range(n)]

fox.sort()

sub = [0]*(n+1)

def bisect(x):
    l, r = 0, n
    while r-l > 1:
        k = (r+l)//2
        if fox[k][0] <= x:
            l = k
        else:
            r = k
    if fox[l][0] <= x:
        return l
    return r


def main():
    ans = 0
    
    for i in range(n):
        if i != 0:
            sub[i] += sub[i-1]
        if fox[i][1]-a*sub[i] <= 0:
            continue
        count = (fox[i][1]-sub[i]*a-1)//a+1
        ans += count
        sub[i] += count
        sub[bisect(fox[i][0]+2*d)+1] -= count

    print(ans)

    
def __starting_point():
    main()

__starting_point()

import math
from bisect import bisect_right

n, d, a = map(int, input().split())
x_list = []
max_x = 0
for _ in range(n):
    x, h = map(int, input().split())
    x -= 1
    x_list.append([x, h])
    max_x = max(max_x, x)
x_list.sort()
xx = [x[0] for x in x_list]
hh = [x[1] for x in x_list]
ans = 0
accum = [0 for _ in range(n)]
for index, [x, h] in enumerate(x_list):
    if index != 0:
        accum[index] += accum[index - 1]
    cnt = max(math.ceil((hh[index] - accum[index]) / a),  0)
    ans += cnt
    index_right = bisect_right(xx, xx[index] + (2 * d))
    accum[index] += cnt * a
    if index_right < n:
        accum[index_right] -= cnt * a
print(ans)

#!/usr/bin/env python3
from collections import deque, Counter
from heapq import heappop, heappush
from bisect import bisect_right

def main():
    N, D, A = list(map(int, input().split()))
    XH = [None] * N
    X = [None] * N

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

    XH.sort()
    X.sort()
    
    ans = 0
    S = [0] * (N+1)# 与えたダメージ
    for i in range(N):
        if S[i] < XH[i][1]:
            # あと何回攻撃する？
            need = (XH[i][1]-S[i]+A-1)//A
            # 爆弾が届く範囲
            j = bisect_right(X,X[i]+2*D)
            # imos法
            S[i] += need*A
            S[j] -= need*A
            ans += need
        S[i+1] += S[i]
    print(ans)


def __starting_point():
    main()

__starting_point()


def resolve():
    N, D, A = map(int, input().split())
    AB = [list(map(int, input().split())) for _ in range(N)]
    AB.sort()

    # imos
    imos = [0] * (N+1)
    ans = 0
    R = 0
    for l in range(N):
        if l:
            imos[l] += imos[l - 1]
        x = AB[l][0]
        h = AB[l][1]
        if imos[l] < h:
            R = max(R, l + 1)
            while R < N and AB[R][0] <= 2 * D + x:
                R += 1
            d = h - imos[l]
            cnt = -(-d//A) # 切り上げ
            imos[l] += cnt * A
            imos[R] -= cnt * A
            ans += cnt
    print(ans)

def __starting_point():
    resolve()
__starting_point()

import bisect
def main():
    N,D,A=map(int,input().split())
    XH=[list(map(int,input().split())) for _ in range(N)]
    XH.sort()
    for i in range(N):
        XH[i][1]=-(-XH[i][1]//A)
    X=[x for x,a in XH]
    far=[0]*N
    for i in range(N):
        far[i]=bisect.bisect_right(X,X[i]+2*D)-1

    ans=0
    carry=0
    outrange=[0]*(N+1)
    for i in range(N):
        x=XH[i][0]
        hp=XH[i][1]
        carry-=outrange[i]
        if carry>=hp:
            continue
        outrange[bisect.bisect_right(X,X[i]+2*D)]+=hp-carry
        ans+=hp-carry
        carry+=hp-carry
    print(ans)

def __starting_point():
    main()
__starting_point()

from collections import deque
N, D, A = map(int, input().split())
monster = []
for k in range(N):
  monster.append(list(map(int, input().split())))
monster.sort(key = lambda x: x[0])
for k in range(N):
  monster[k][1] = int((monster[k][1]-0.1)//A + 1)
ans = 0
monster = deque(monster)
final = monster[-1][0]
ruiseki = 0
minuslist = deque()

while len(monster) > 0:
  while len(minuslist) > 0:
    if monster[0][0] >= minuslist[0][0]:
      ruiseki -= minuslist[0][1]
      minuslist.popleft()
    else:
      break
  if ruiseki < monster[0][1]:
    ans += monster[0][1] - ruiseki
    if monster[0][0] + 2*D +1 <= final:
      minuslist.append([monster[0][0]+2*D+1, monster[0][1] - ruiseki])
    ruiseki = monster[0][1]
  monster.popleft()

print(ans)

from collections import deque
from math import ceil

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

que = deque()

ans = 0
atack = 0
for x,h in M:
  while len(que) > 0 and que[0][0] < x:
    tx,ta = que.popleft()
    atack -= ta      
  
  bomb_num = max(0, h-atack)
  atack += bomb_num
  ans += bomb_num
  
  if bomb_num > 0:
    que.append([x+d*2,bomb_num])

print(ans)  

import math

I = lambda: list(map(int, input().split()))
n, d, a = I()
l = []
for _ in range(n):
	x, y = I()
	l.append([x,y])
l.sort()

j = 0
limit = []
for i in range(n):
	while l[j][0] - l[i][0] <= 2*d:
		j+=1
		if j == n: break
	j-=1
	limit.append(j)

ans = 0
num=[0]*(n+1)
cnt=0
for i in range(n):
	l[i][1]-=(ans-cnt)*a
	damage_cnt=max(0,(l[i][1]-1)//a + 1)
	ans+=damage_cnt
	num[limit[i]]+=damage_cnt
	cnt+=num[i]
print(ans)

from bisect import *
def solve():
  ans = 0
  N, D, A = list(map(int, input().split()))
  B = [list(map(int, input().split())) for _ in range(N)]
  B.sort()
  lasts = [0]*(N+1)
  now = 0
  for i,((x,h),l) in enumerate(zip(B,lasts)):
    now -= l
    atack = max(0,-(-(h-now)//A))
    ans += atack
    damage = atack*A
    now += damage
    last = x+2*D
    ind = bisect_right(B,[last+1,0])
    lasts[ind] += damage
  return ans
print((solve()))


def binary(N, LIST, num):  # 二分探索 # N:探索要素数
    l, r = -1, N
    while r - l > 1:
        if LIST[(l + r) // 2] > num:  # 条件式を代入
            r = (l + r) // 2
        else:
            l = (l + r) // 2
    return r + 1


n, d, a = list(map(int, input().split()))
xh = sorted(list(map(int, input().split())) for _ in range(n))
x = [i for i, j in xh]
h = [(j + a - 1) // a for i, j in xh]

bomb, bsum, ans = [0] * (n + 1), [0] * (n + 1), 0
for i in range(n):
    j = binary(n, x, x[i] + 2 * d) - 1
    bsum[i] += bsum[i - 1] + bomb[i]
    bnum = max(h[i] - bsum[i], 0)
    bomb[i] += bnum
    bomb[j] -= bnum
    bsum[i] += bnum
    ans += bnum
print(ans)


from collections import deque
import math

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

# 爆発範囲がとても広く、全ての爆発が右端まで及ぶとひとまず考える
# 各xを見る際に、影響の及ばない爆発分のダメージは引く

# 合計の爆発回数
ans = 0
# 爆発ダメージの合計
total_damage = 0
# 各爆発の情報
dq = deque()

# 左端から順にモンスターを見る
for x, h in XH:
    # 爆発が及ばない場合
    while dq and dq[0][1] < x:
        dmg, rng = dq.popleft()
        total_damage -= dmg

    # 爆発させる必要がある場合
    if total_damage < h:
        # 残っているHPに更新
        h -= total_damage
        # 必要な爆発回数
        cnt = math.ceil(h / A)
        ans += cnt
        # 爆発回数 * 単発のダメージ
        dmg = cnt * A
        total_damage += dmg
        # [爆発で与えるダメージ、及ぶ範囲の右端]
        dq.append((dmg, x + D * 2))

print(ans)


import math
import sys
from collections import deque


def input():
    return sys.stdin.readline().strip()


sys.setrecursionlimit(20000000)

MOD = 10 ** 9 + 7
INF = float("inf")


def main():
    N, D, A = list(map(int, input().split()))
    monster = [list(map(int, input().split())) for _ in range(N)]

    monster.sort(key=lambda x: x[0])

    attack = []
    for i in range(N):
        attack.append(math.ceil(monster[i][1] / A))

    acc_damage = 0
    attacked = deque([])
    answer = 0

    for i in range(N):
        x = monster[i][0]
        h = attack[i]

        while attacked and x > attacked[0][0]:
            limit, damage = attacked.popleft()
            acc_damage -= damage

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

        acc_damage += need

        if need:
            attacked.append((x + 2 * D, need))

    print(answer)


def __starting_point():
    main()

__starting_point()

import bisect
import operator
import collections
import sys
input = sys.stdin.readline


class RAQ():
    
    def __init__(self, size):
        """初期化"""
        self.size = size
        self.sub = [0 for i in range(size + 1)]
        self.r = 0
        self.v = 0
    
    @classmethod
    def from_array(cls, a):
        st = cls(len(a))
        for i, x in enumerate(a):
            st.add(i, i+1, x)
        return st

    def add(self, a, b, value):
        """区間[a, b) に対する加算"""
        if a > b:
            raise ValueError("a must be less than equal b.")
        self.sub[a] += value
        self.sub[b] -= value

    def get(self, key):
        """値の取得"""
        if key < self.r - 1:
            self.r = 0
            self.v = 0
        for i in range(self.r, key):
            self.v += self.sub[i]
        self.r = key
        return self.v + self.sub[key]


def read():
    N, D, A = list(map(int, input().strip().split()))
    XH = list()
    for i in range(N):
        x, h = list(map(int, input().strip().split()))
        XH.append((x, h))
    return N, D, A, XH


def solve(N, D, A, XH):
    XH = sorted(XH)
    X = [x for x, h in XH]
    H = [h for x, h in XH]

    st = RAQ.from_array(H)

    ans = 0
    i = 0
    while i < N:
        x = XH[i][0]
        h = st.get(i)
        c = h // A + (h % A > 0)
        ans += c
        v = c * A
        lidx = bisect.bisect_left(X, x)
        ridx = bisect.bisect_left(X, x + 2 * D + 1)
        st.add(lidx, ridx, -v)
        m = -1
        i += 1
        while i < N:
            h = st.get(i)
            if h > 0:
                break
            i += 1
    return ans


def __starting_point():
    inputs = read()
    print(("%s" % solve(*inputs)))

__starting_point()

def binary(N, LIST, num):  # 二分探索 # N:探索要素数
    l, r = -1, N
    while r - l > 1:
        if LIST[(l + r) // 2] > num:  # 条件式を代入
            r = (l + r) // 2
        else:
            l = (l + r) // 2
    return r + 1


n, d, a = list(map(int, input().split()))
xh = sorted(list(map(int, input().split())) for _ in range(n))
x = [i for i, j in xh]
h = [(j + a - 1) // a for i, j in xh]

bomb, bsum, ans = [0] * (n + 1), [0] * (n + 1), 0
for i in range(n):
    j = binary(n, x, x[i] + 2 * d) - 1
    bnum = max(h[i] - (bsum[i - 1] + bomb[i]), 0)
    bomb[i] += bnum
    bomb[j] -= bnum
    bsum[i] += bsum[i - 1] + bomb[i]
    ans += bnum
print(ans)


from collections import deque
N, D, A = list(map(int, input().split()))
pair_xh = [[-1, -1] for _ in range(N)] # 1回ずつしか使わないけどソートするから必要
for i in range(N):
    pair_xh[i][0], pair_xh[i][1] = list(map(int, input().split()))
pair_xh.sort(key = lambda x: x[0]) #座標でソート

q_lim_d = deque() # 累積和に含まれる攻撃範囲とダメージを保存する場所
total = 0 # 喰らいダメージの累積和
count = 0 # 攻撃回数
for i in range(N):
    x = pair_xh[i][0]
    h = pair_xh[i][1]
    
    while len(q_lim_d) and q_lim_d[-1][0] < x: # 範囲外になったら喰らわないから累積和から外す
        total -= q_lim_d[-1][1]
        q_lim_d.pop()
    h -= total
    if h > 0: # 見てる敵の体力が0になる攻撃回数を求めその分を累積和に足す
        times = (h + A - 1) // A # 0にするのに必要な回数(切り上げ)
        count += times
        damage = A * times
        total += damage
        q_lim_d.appendleft([x + 2 * D, damage])
print(count)

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)


import bisect
import operator
import collections


class RAQ():
    
    def __init__(self, size):
        """初期化"""
        self.size = size
        self.sub = [0 for i in range(size + 1)]
        self.r = 0
        self.v = 0
    
    @classmethod
    def from_array(cls, a):
        st = cls(len(a))
        for i, x in enumerate(a):
            st.add(i, i+1, x)
        return st

    def add(self, a, b, value):
        """区間[a, b) に対する加算"""
        if a > b:
            raise ValueError("a must be less than equal b.")
        self.sub[a] += value
        self.sub[b] -= value

    def get(self, key):
        """値の取得"""
        if key < self.r - 1:
            self.r = 0
            self.v = 0
        for i in range(self.r, key):
            self.v += self.sub[i]
        self.r = key
        return self.v + self.sub[key]


def read():
    N, D, A = list(map(int, input().strip().split()))
    XH = list()
    for i in range(N):
        x, h = list(map(int, input().strip().split()))
        XH.append((x, h))
    return N, D, A, XH


def solve(N, D, A, XH):
    XH = sorted(XH)
    X = [x for x, h in XH]
    H = [h for x, h in XH]

    st = RAQ.from_array(H)

    ans = 0
    i = 0
    while i < N:
        x = XH[i][0]
        h = st.get(i)
        c = h // A + (h % A > 0)
        ans += c
        v = c * A
        lidx = bisect.bisect_left(X, x)
        ridx = bisect.bisect_left(X, x + 2 * D + 1)
        st.add(lidx, ridx, -v)
        m = -1
        i += 1
        while i < N:
            h = st.get(i)
            if h > 0:
                break
            i += 1
    return ans


def __starting_point():
    inputs = read()
    print(("%s" % solve(*inputs)))

__starting_point()

from math import ceil


def binary(N, LIST, num):  # 二分探索 # N:探索要素数
    l, r = -1, N
    while r - l > 1:
        if LIST[(l + r) // 2] > num:  # 条件式を代入
            r = (l + r) // 2
        else:
            l = (l + r) // 2
    return r + 1


n, d, a = list(map(int, input().split()))
xh = sorted(list(map(int, input().split())) for _ in range(n))
x = [i for i, j in xh]
h = [j for i, j in xh]

bomb, bsum, ans = [0] * (n + 1), [0] * (n + 1), 0
for i in range(n):
    j = binary(n, x, x[i] + 2 * d) - 1
    bsum[i] += bsum[i - 1] + bomb[i]
    bnum = max(ceil(h[i] / a - bsum[i]), 0)
    bomb[i] += bnum
    bomb[j] -= bnum
    bsum[i] += bnum
    ans += bnum
print(ans)


from bisect import bisect
from collections import defaultdict

N, D, A = map(int, input().split())
XH = []

for _ in range(N):
  X, H = map(int, input().split())
  XH.append((X, -(-H//A)))

XH.sort()
Xs = [ xh[0] for xh in XH ]
HP = [ xh[1] for xh in XH ]

XR = []
for x in Xs:
  XR.append(bisect(Xs, x+2*D))

cnt = 0
temp = 0
D = defaultdict(int)

for i in range(N):
  temp -= D[i]
  HP[i] -= temp
  if HP[i] > 0:
    temp += HP[i]
    cnt += HP[i]
    D[XR[i]] += HP[i]
    HP[i] -= temp

print(cnt)

from itertools import accumulate
import math
import bisect

n,d,a = map(int,input().split())
xh = [tuple(map(int,input().split())) for _ in range(n)]
xh.sort()
x = [xh[i][0] for i in range(n)]
h = [xh[i][1] for i in range(n)]
damage = [0]*(n+1)
point = 0

for i in range(n):
    if i != 0:
        damage[i] += damage[i-1]
    bi = bisect.bisect(x,2*d+x[i])
    count = max(math.ceil((h[i]-damage[i])/a),0)
    damage[i] += a*count
    damage[bi] -= a*count
    point += count
    
print(point)

import sys
from collections import deque

sys.setrecursionlimit(10 ** 6)
INF = float("inf")
MOD = 10 ** 9 + 7


def input():
    return sys.stdin.readline().strip()


def main():
    N, D, A = list(map(int, input().split()))
    monster = {}
    X = []
    for _ in range(N):
        x, h = list(map(int, input().split()))
        monster[x] = h
        X.append(x)

    X.sort()

    # x, damage
    q = deque([])

    acc_damage = 0

    ans = 0
    for i in range(N):
        x = X[i]
        h = monster[x]

        while q and q[0][0] < x:
            p, damage = q.popleft()
            acc_damage -= damage

        if h - acc_damage <= 0:
            continue

        cnt = (h - acc_damage + A - 1) // A
        ans += cnt
        acc_damage += cnt * A

        q.append((x + 2 * D, cnt * A))

    print(ans)


def __starting_point():
    main()

__starting_point()

import math
from collections import deque

n, d, a = list(map(int, input().split()))
xh = [list(map(int, input().split())) for _ in range(n)]
xh.sort(key=lambda x:x[0])
xh = deque(xh)

xh_field = deque()

cnt = 0
now_damage = 0
while xh:
    pos, hp = xh.popleft()
    if xh_field:
        while (xh_field and xh_field[0][0] < pos) :
            now_damage -= a * xh_field[0][1]
            xh_field.popleft() 
    if hp <= now_damage:
        pass
    elif hp > now_damage:
        atk_cnt = math.ceil((hp - now_damage) / a)
        cnt += atk_cnt
        now_damage += atk_cnt * a
        xh_field.append((2*d + pos, atk_cnt))        
print(cnt)


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

hit = []

for i in range(n):
  x, h = map(int,input().split())
  hit.append([x,h])
hit.sort()

que = []
ans = 0
bomb = 0
for i in range(n):
  while True:
    if len(que) == 0:
      break
    if hit[i][0] <= que[0][0]:
      break
    bomb -= que[0][1]
    que.pop(0)
  r = hit[i][1] - bomb
  if r < 0:
    continue
  c = (r + a - 1)//a
  ans += c
  bomb += c*a
  que.append((hit[i][0]+2*d,c*a))
print (ans)

#!/usr/bin/env python3

from math import ceil
import heapq

def main():
    n, d, a = list(map(int, input().split()))
    q = []
    for i in range(n):
        x, h = list(map(int, input().split()))
        heapq.heappush(q, (x, 0, ceil(h / a)))
    bomb = 0
    res = 0
    while q:
        x, ty, h = heapq.heappop(q)
        if ty == 0:
            if h > bomb:
                heapq.heappush(q, (x + 2 * d, 1, h - bomb))
                res += h - bomb
                bomb = h
        else:
            bomb -= h
    print(res)

def __starting_point():
    main()

__starting_point()

N, D, A = list(map(int, input().split()))
monster = []
for k in range(N):
  monster.append(list(map(int, input().split())))
monster.sort(key = lambda x: x[0])
for k in range(N):
  monster[k][1] = int((monster[k][1]-0.1)//A + 1)
ans = 0

final = monster[-1][0]
ruiseki = 0
minuslist = []
j = 0
for k in range(N):
  while (j < len(minuslist)):
    if monster[k][0] >= minuslist[j][0]:
      ruiseki -= minuslist[j][1]
      j += 1
    else:
      break
  if ruiseki < monster[k][1]:
    ans += monster[k][1] - ruiseki
    if monster[k][0] + 2*D +1 <= final:
      minuslist.append([monster[k][0]+2*D+1, monster[k][1] - ruiseki])
    ruiseki = monster[k][1]


print(ans)


import sys
from collections import deque

sys.setrecursionlimit(10 ** 7)
f_inf = float('inf')
mod = 10 ** 9 + 7


def resolve():
    n, d, a = list(map(int, input().split()))
    XH = sorted([list(map(int, input().split())) for _ in range(n)])

    res = 0
    tt_dmg = 0
    que = deque()
    for x, h in XH:
        while que and que[0][1] < x:
            dmg, rng = que.popleft()
            tt_dmg -= dmg

        if tt_dmg < h:
            h -= tt_dmg
            cnt = (h + a - 1) // a
            res += cnt
            dmg = cnt * a
            tt_dmg += dmg
            que.append((dmg, x + d * 2))

    print(res)


def __starting_point():
    resolve()

__starting_point()


def resolve():
    N, D, A = list(map(int, input().split()))
    AB = [list(map(int, input().split())) for _ in range(N)]
    AB.sort()

    # imos
    imos = [0] * (N+1)
    ans = 0
    R = 0
    for l in range(N):
        if l:
            imos[l] += imos[l - 1]
        x = AB[l][0]
        h = AB[l][1]
        if imos[l] < h:
            R = max(R, l + 1)
            while R < N and AB[R][0] <= 2 * D + x:
                R += 1
            d = h - imos[l]
            cnt = (d+A-1) // A
            imos[l] += cnt * A
            imos[R] -= cnt * A
            ans += cnt
    print(ans)

def __starting_point():
    resolve()

__starting_point()

#!/usr/bin/env python3
import sys
from collections import deque
def input(): return sys.stdin.readline().rstrip()


def main():
    N, D, A = list(map(int, input().split()))
    mlist = []
    for _ in range(N):
        x, h = list(map(int, input().split()))
        mlist.append([x, (h+A-1)//A])
    mlist.sort(key=lambda x: x[0])
    db = deque()
    dnotb = deque()
    left = mlist[0][0]
    ans = 0
    for monster in mlist:
        if monster[0] <= left+2*D:
            db.append(monster)
        else:
            dnotb.append(monster)
    ans = 0
    while db or dnotb:
        if not db:
            monster = dnotb.popleft()
            monster[1] += ans
            db.append(monster)
        bmonster = db.popleft()
        while dnotb:
            if dnotb[0][0] <= bmonster[0]+2*D:
                monster = dnotb.popleft()
                monster[1] += ans
                db.append(monster)
            else:
                break
        ans = max(ans, bmonster[1])
    print(ans)


def __starting_point():
    main()

__starting_point()

#problems2
#silver fox vs monster
import math
N,D,A=map(int,input().split())
d=[]
for _ in range(N):
    x,h=map(int,input().split())
    d.append((x,h))
d.sort(key=lambda x:x[0])

now_damage=0
from collections import deque
d=deque(d)
ans=0
d_field=deque()
while d:
    x=d.popleft()
    place,life=x
    if d_field:
        while (d_field and d_field[0][0]<place) :
            now_damage-=A*d_field[0][1]
            d_field.popleft()      
    if life<=now_damage:
        pass
    elif life>now_damage:
        K=math.ceil((life-now_damage)/A)
        ans+=K
        now_damage+=K*A
        d_field.append((2*D+place,K))        
print(ans)

from collections import deque
import math

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

# 爆発範囲がとても広く、全ての爆発が右端まで及ぶとひとまず考える
# 各xを見る際に、影響の及ばない爆発分のダメージは引く

# 合計の爆発回数
ans = 0
# 爆発ダメージの合計
total_damage = 0
# 各爆発の情報
dq = deque()

# 左端から順にモンスターを見る
for x, h in XH:
    # 爆発が及ばない場合
    while dq and dq[0][1] < x:
        dmg, rng = dq.popleft()
        total_damage -= dmg

    # 爆発させる必要がある場合
    if total_damage < h:
        # 残っているHPに更新
        h -= total_damage
        # 必要な爆発回数
        # cnt = math.ceil(h // A)
        cnt = (h + A - 1) // A
        ans += cnt
        # 爆発回数 * 単発のダメージ
        dmg = cnt * A
        total_damage += dmg
        # [爆発で与えるダメージ、及ぶ範囲の右端]
        dq.append((dmg, x + D * 2))

print(ans)


from collections import deque
import math

import sys
input = sys.stdin.readline

N, D, A = list(map(int, input().split()))
S = [0]*N
atack = deque()
for i in range(N):
    x, h = list(map(int, input().split()))
    S[i] = [x, h]

S.sort()
cnt = 0
dmg = 0
for i in range(N):
    while atack:
        if atack[0][0] < S[i][0]:
            x, d = atack.popleft()
            dmg -= d
        else:
            break

    if S[i][1] <= dmg:
        continue
    bomb = math.ceil((S[i][1]-dmg)/A)
    atack.append([S[i][0]+2*D, A*bomb])
    cnt += bomb
    dmg += A*bomb

print(cnt)


# 解説放送の方針
# ダメージが消える右端をキューで管理
# 右端を超えた分は、累積ダメージから引いていく

from collections import deque

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

XH = sorted(XH)
que=deque()
cum = 0
ans = 0
for i in range(N):
  x,h = XH[i]
  if i == 0:
    r,n = x+2*D,(h+A-1)//A
    d = n*A
    cum += d
    que.append((r,d))
    ans += n
    continue
  while que and que[0][0]<x:
    r,d = que.popleft()
    cum -= d
  h -= cum
  if h<0:
    continue
  r,n = x+2*D,(h+A-1)//A
  d = n*A
  cum += d
  que.append((r,d))
  ans += n
  
print(ans)

from bisect import bisect_right

n, d, a = list(map(int, input().split()))
xh = sorted(list(map(int, input().split())) for _ in range(n))
x = [0] * (n + 1)
h = [0] * (n + 1)
s = [0] * (n + 1)

for i, (f, g) in enumerate(xh):
    x[i], h[i] = f, g
x[n] = 10 ** 10 + 1
ans = 0
for i in range(n):
    if i > 0:
        s[i] += s[i - 1]
    h[i] -= s[i]
    if h[i] > 0:
        num = 0 - - h[i] // a
        ans += num
        s[i] += num * a

        j = bisect_right(x, x[i] + d * 2)
        s[j] -= num * a
print(ans)


from bisect import bisect_left, bisect_right
import sys
input = sys.stdin.readline

def solve():
    def makeBIT(numEle):
        numPow2 = 2 ** (numEle-1).bit_length()
        data = [0] * (numPow2+1)
        return data, numPow2
    def setInit(As):
        for iB, A in enumerate(As, 1):
            data[iB] = A
        for iB in range(1, numPow2):
            i = iB + (iB & -iB)
            data[iB] -= data[i]
    def addValue(iA, A):
        iB = iA + 1
        while iB > 0:
            data[iB] += A
            iB -= iB & -iB
    def getValue(iA):
        iB = iA + 1
        ans = 0
        while iB <= numPow2:
            ans += data[iB]
            iB += iB & -iB
        return ans


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

    XHs.sort()
    Xs, Hs = [], []
    for X, H in XHs:
        Xs.append(X)
        Hs.append(H)

    data, numPow2 = makeBIT(N)
    setInit(Hs)

    ans = 0
    for i in range(N):
        rest = getValue(i)
        if rest <= 0: continue
        pos = Xs[i] + D
        iR = bisect_right(Xs, pos + D) - 1
        num = -(-rest // A)
        ans += num
        damage = num*A
        addValue(iR, -damage)

    print(ans)


solve()


n, d, a = map(int, input().split())
xh = []
for _ in range(n):
    x, h = map(int, input().split())
    h = (h - 1) // a + 1
    xh.append([x, h])
xh.sort()
damage = xh[0][1]
ans = damage
damage_lst = [[xh[0][0] + d * 2, damage]]
pos = 0
for i, (x, h) in enumerate(xh[1:], start = 1):
    while x > damage_lst[pos][0]:
        damage -= damage_lst[pos][1]
        pos += 1
        if pos == i:
            break
    damage_tmp = max(h - damage, 0)
    ans += damage_tmp
    damage += damage_tmp
    damage_lst.append([x + d * 2, damage_tmp])
print(ans)

N,D,A = map(int,input().split())
XH = [list(map(int,input().split())) for i in range(N)]
XH.sort()
from math import ceil
times = ceil(XH[0][1]/A)
ans = times
damege = [times*A]
coor = [XH[0][0]+2*D]
start = 0
end = 1
dam = sum(damege[start:end])
for i in range(1,N):
    st = start
    while start < end and coor[start] < XH[i][0]:
        start += 1
    dam -= sum(damege[st:start])
    H = XH[i][1] - dam
    if H > 0:
        times = ceil(H/A)
        ans += times
        damege.append(times*A)
        dam += times*A
        coor.append(XH[i][0]+2*D)
        end += 1
print(ans)

from collections import deque
import sys 
input = sys.stdin.readline
N, D, A = list(map(int, input().split()))
xh = [list(map(int, input().split())) for _ in range(N)]
xh = sorted(xh)
total = 0 # 今与えているダメージの総和
D = 2*D
ans = 0
q = deque()
for i in range(N):
  x, h = xh[i]
  # 今いる場所が前回までの爆撃の範囲外になるならその分totalから引く
  while len(q) >= 1 and q[0][0] < x:
    total -= q.popleft()[1]
  h -= total

  if h > 0:
    num = (h-1)//A+1
    ans += num
    damage = num*A
    total += damage
    q += ([[x+D, damage]])

print(ans)


from sys import stdin
from collections import deque
def main():
    #入力
    readline=stdin.readline
    n,d,a=map(int,readline().split())
    xh=[list(map(int,readline().split())) for _ in range(n)]
    xh.sort()
    x=[0]*n
    h=[0]*n
    for i in range(n):
        x[i],h[i]=xh[i][0],xh[i][1]

    dq=deque()
    now=0
    cnt=0
    for i in range(n):
        if i==0:
            cnt+=(h[i]+a-1)//a
            now+=(h[i]+a-1)//a*a
            dq.append([x[i]+2*d,now])
        else:
            while len(dq)!=0 and dq[0][0]<x[i]:
                tmp=dq.popleft()
                now-=tmp[1]
            if h[i]<=now:
                pass
            else:
                dq.append([x[i]+2*d,(h[i]-now+a-1)//a*a])
                cnt+=(h[i]-now+a-1)//a
                now+=(h[i]-now+a-1)//a*a

    print(cnt)

def __starting_point():
    main()
__starting_point()

from collections import deque
from math import ceil

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

ms = [list(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)  


from heapq import heappush, heappop

n, d, a = list(map(int, input().split()))
actions = []
for _ in range(n):
    x, h = list(map(int, input().split()))
    heappush(actions, (x, 0, (h + a - 1) // a))
cnt = 0
bomb = 0
current_bomb = 0
while cnt < n:
    a, c, b = heappop(actions)
    if c:
        current_bomb -= b
        continue
    else:
        HP = b
        if HP <= current_bomb:
            cnt += 1
            continue
        else:
            HP -= current_bomb
            cnt += 1
            current_bomb += HP
            bomb += HP
            heappush(actions, (a + 2 * d, 1, HP))
print(bomb)


# 解説放送
# 解説PDFは「効果範囲がどのモンスターか」を事前に求めているが、
# 解説放送ではキューを使うことで「効果範囲がどのモンスターか」を求めず、座標のみでうまく処理している
# 解説放送だとBITを使った解法もある

# 貪欲の方針は見えやすい。そこから2つの難題がある
# (1) 効果範囲。単純に調べるとO(N^2)
# → 二分探索、尺取り法（事前に全計算でも逐次処理と同時に計算でも良い）
# (2) HPの減算。多数の要素に対してAを引く必要があり、最悪O(N^2)
# →一定範囲に-Aするのは時間がかかるけど、最初に-Aして最後に+Aすれば2要素を変えるだけで済むね（imos法）

n, d, a = list(map(int, input().split()))
enemies = [list(map(int, input().split())) for _ in range(n)]

enemies.sort(key= lambda a: a[0])  # 座標を基準にソート

d *= 2
total_damage = 0

import collections
q = collections.deque()

ans = 0
for i in range(n):
    x = enemies[i][0]
    hp = enemies[i][1]

    while (len(q) and q[0][0] < x):
        total_damage -= q[0][1]
        q.popleft()
    
    hp -= total_damage
    if hp > 0:
        times = (hp+a-1) // a
        total_damage += a * times
        ans += times

        q.append((x+d, a*times))

print(ans)

import bisect
import sys

def main():
  input = sys.stdin.readline
  n, d, a = map(int, input().split())
  fox = [None]*n
  for i in range(n):
    x, h = map(int, input().split())
    fox[i] = (x, h)

  fox.sort()
  x = [int(fox[i][0]) for i in range(n)]
  h = [int(fox[i][1]) for i in range(n)]

  ans = 0
  bit = [0]*n
  for i in range(n):
    if i != 0:
      bit[i] += bit[i-1]
    sub = max([(h[i]-bit[i]-1)//a+1, 0])
    ans += sub
    bit[i] += sub*a
    index = bisect.bisect_right(x, x[i]+2*d)
    if index != n:
      bit[index] -= sub*a
  print(ans)

def __starting_point():
  main()
__starting_point()

import bisect
n, d, a = map(int, input().split())
fox = [None]*n
for i in range(n):
  x, h = map(int, input().split())
  fox[i] = (x, h)

fox.sort()
x = [int(fox[i][0]) for i in range(n)]
h = [int(fox[i][1]) for i in range(n)]

ans = 0
bit = [0]*n
for i in range(n):
  if i != 0:
    bit[i] += bit[i-1]
  if bit[i] >= h[i]:
    continue
  sub = (h[i]-bit[i]-1)//a+1
  ans += sub
  bit[i] += sub*a
  index = bisect.bisect_right(x, x[i]+2*d)
  if index == n:
    continue
  bit[index] -= sub*a
print(ans)

n,d,a=map(int,input().split())
d=d*2
M=sorted([list(map(int,input().split())) for i in range(n)])
l=0
A=[0]*n
B=[0]
ans=0
for i in range(n):
  while M[l][0]+d<M[i][0]:
    l=l+1
  ans=ans+max(0,(M[i][1]-B[i]+B[l]+a-1)//a)
  A[i]=max(0,(M[i][1]-B[i]+B[l]+a-1)//a)*a
  B.append(B[-1]+A[i])
print(ans)

#!/usr/bin/env python3

from math import ceil
import heapq

def main():
    n, d, a = list(map(int, input().split()))
    q = []
    for i in range(n):
        x, h = list(map(int, input().split()))
        heapq.heappush(q, (x, -(h // a + (1 if (h % a) else 0))))
    bomb = 0
    res = 0
    while q:
        x, h = heapq.heappop(q)
        if h < 0:
            h *= -1
            if h > bomb:
                heapq.heappush(q, (x + 2 * d, h - bomb))
                res += h - bomb
                bomb = h
        else:
            bomb -= h
    print(res)

def __starting_point():
    main()

__starting_point()

N, D, A = map(int, input().split())

Monster = [0]*N
for i in range(N):
    Monster[i] = list(map(int, input().split()))

Monster.sort(key=lambda x:x[0])

from bisect import bisect_left, bisect_right, bisect, insort_left, insort_right, insort

from collections import deque

d = deque()
damage = 0
ans = 0
for i in range(N):
    while len(d)>0:
        a = d.popleft()
        if a[0]==i:
            damage -= a[1]
        else:
            d.appendleft(a)
            break
    Monster[i][1] -= damage
    count = -(-max(Monster[i][1],0)//A)
    ans += count
    right = Monster[i][0]+2*D
    ind = bisect(Monster,[right,10**9+1])
    damage += A*count
    d.append([ind,A*count])
print(ans)