CodeEff/ECCO huggingface dataset:
# Original solution
from math import ceil
from collections import deque

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

ans = 0
acc = 0
deq = deque([])

for x, h in Monsters:
  while deq and x>deq[0][0]:
    lim, dam = deq.popleft()
    acc -= dam
  c = max(0, h-acc)
  ans += c
  acc += c
  if c:
    deq += [(x+2*D, c)]
    
print(ans)

# Optimized solution
from collections import deque
N, D, A = list(map(int, input().split()))
ls = []
for i in range(N):
  x,h = list(map(int, input().split()))
  h = h//A if h%A==0 else h//A+1
  ls += [(x,h)]
ls.sort(key=lambda x:x[0])
deq = deque([])
ans = 0
acc = 0
for i in range(N):
  x, h = ls[i]
  while deq and deq[0][0]<x:
    y, d = deq.popleft()
    acc -= d
  n = max(0,h-acc)
  ans += n
  acc += n
  if n:
    deq += [(x+2*D,n)]
print(ans)
# Original solution
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)


if __name__ == '__main__':
    resolve()


# Optimized solution
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)


if __name__ == '__main__':
    resolve()
# Original solution
n, d, a  = list(map(int,input().split()))
x_b = []
x_b2 = []
x = [0]*n
h_b = []
h = [0]*n
for i in range(n):
    x_temp,h_temp = list(map(int,input().split()))
    x_b.append({'key':i, 'val':x_temp})
    x_b2.append(x_temp)
    h_b.append(h_temp)

x_b.sort(key = lambda x_b : x_b['val'])

for i in range(n):
    ind = x_b[i]['key']
    x[i] = x_b2[ind]
    h[i] = h_b[ind]

ans = 0
for i in range(n):
    if (h[i] <= 0):
        continue
    at_num = ((h[i] -1 )// a) + 1
    ans += at_num
    h[i] -= at_num * a
    x_origin = x[i]
    while(True):
        i += 1
        if(i >= n):
            break
        if(x_origin + 2*d >= x[i]):
            h[i] -= at_num * a
        else:
            break

print(ans)

# Optimized solution
import sys
input = sys.stdin.readline
# 二分木
import bisect


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

xh.sort()
x = [ tmp[0] for tmp in xh]
damage = [0] * (n+1)

ans = 0
for i in range(n):
    damage[i+1] += damage[i]
    if( damage[i+1] >= xh[i][1] ):
        continue
    atk_num = (xh[i][1] - damage[i+1] - 1)//a +1
    ans += atk_num
    damage[i+1] += atk_num * a
    right = bisect.bisect_right(x, xh[i][0] + 2*d)
    if( right < n):
        damage[right+1] -= atk_num * a

print(ans)
# Original solution
import math
import bisect
import sys
input = sys.stdin.readline

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

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

X=[0]*N
for i in range(N):
    X[i]=XH[i][0]


#bの倍数の中でaを超える最小
def calc(a,b):
    return math.ceil(a/b)*b

ans=0
for i in range(N):
    if XH[i][1]>0:
        bom=X[i]+D
        Lb=i
        Rb=bisect.bisect_right(X,bom+D)
        ans+=XH[i][1]//A
        if XH[i][1]%A!=0:
            ans+=1
        dam=calc(XH[i][1],A)
        for j in range(Lb,Rb):
            XH[j][1]-=dam
        
print(ans)
    
    
    
    





# Optimized solution
import math
import bisect
import sys
input = sys.stdin.readline

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

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

X=[0]*N
for i in range(N):
    X[i]=XH[i][0]



ans=0
S=[0]*(N+1)#累積和


for i in range(N):
    if S[i]<XH[i][1]:
        bom=X[i]+D
        Lb=i
        Rb=bisect.bisect_right(X,bom+D)
        num=(XH[i][1]-S[i])//A
        if (XH[i][1]-S[i])%A!=0:
            num+=1
        ans+=num
        dam=num*A
        #imosで遅延
        S[Lb]+=dam
        S[Rb]-=dam
    S[i+1]+=S[i]
        
print(ans)
# Original solution
from operator import itemgetter
from bisect import bisect_right
n, d, a = list(map(int, input().split()))
monster = [tuple(map(int, input().split())) for _ in range(n)]
monster.sort(key=itemgetter(0))
xx = [xi for xi, hi in monster]

ans = 0
imos = [0] * (n + 1)
for i, (xi, hi) in enumerate(monster):
    hi -= imos[i]
    if hi > 0:
        c = (hi + a - 1) // a
        ans += c
        idx = bisect_right(xx, xi + 2 * d)
        imos[i] += c * a
        imos[idx] -= c * a

    # update imos
    imos[i + 1] += imos[i]

print(ans)


# Optimized solution
from operator import itemgetter
from bisect import bisect_right
import sys
input = sys.stdin.readline

n, d, a = list(map(int, input().split()))
monster = [tuple(map(int, input().split())) for _ in range(n)]
monster.sort(key=itemgetter(0))
xx = [xi for xi, hi in monster]

ans = 0
imos = [0] * (n + 1)
for i, (xi, hi) in enumerate(monster):
    hi -= imos[i]
    if hi > 0:
        c = (hi + a - 1) // a
        ans += c
        idx = bisect_right(xx, xi + 2 * d)
        imos[i] += c * a
        imos[idx] -= c * a

    # update imos
    imos[i + 1] += imos[i]

print(ans)
# Original solution
N, D, A = list(map(int, input().split()))
XH = [list(map(int, input().split())) for _ in range(N)]

XH = sorted(XH)

for i in range(N):
    XH[i][1] = (XH[i][1] + A - 1) // A

adjust = [0 for _ in range(N + 1)]

ans = 0
done = 0

for i in range(N):
    done -= adjust[i]
    XH[i][1] -= done
    if XH[i][1] < 0: continue

    v = XH[i][0] + 2 * D
    ng = 0
    ok = N
    while abs(ok - ng) > 1:
        mid = (ok + ng) // 2
        if XH[mid][0] > v: ok = mid
        else: ng = mid

    ans += XH[i][1]
    done += XH[i][1]
    adjust[ok] += XH[i][1]

print(ans)

# Optimized solution
import sys
N, D, A = list(map(int, sys.stdin.readline().split()))
XH = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]

XH = sorted(XH)

for i in range(N):
    XH[i][1] = (XH[i][1] + A - 1) // A

adjust = [0 for _ in range(N + 1)]

def findi(v):
    ng = 0
    ok = N
    while abs(ok - ng) > 1:
        mid = (ok + ng) // 2
        if XH[mid][0] > v: ok = mid
        else: ng = mid
    return ok

ans = 0
done = 0

for i in range(N):
    done -= adjust[i]
    XH[i][1] -= done
    if XH[i][1] < 0: continue

    ans += XH[i][1]
    index = findi(XH[i][0] + D * 2)
    done += XH[i][1]
    adjust[index] += XH[i][1]

print(ans)
# Original solution
from collections import deque
from math import ceil
import sys
input = sys.stdin.readline

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

    ans = 0
    index = deque()
    damage = 0
    for i in range(N):
        # 爆弾が届かない場合
        while index:
            if index[0][0] + 2*D < XH[i][0]:
                _,c = index.popleft()
                damage -= A * c
            else:
                break
        
        # 爆弾投下
        XH[i][1] -= damage

        # 生き残り
        if XH[i][1] > 0:
            count = ceil(XH[i][1]/A)
            damage += count * A
            index.append([XH[i][0],count])
            ans += count

    print(ans)

if __name__ == "__main__":
    main()

# Optimized solution
# try AfterContestCase
from collections import deque
from math import ceil
import sys
input = sys.stdin.readline

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

    ans = 0
    index = deque()
    damage = 0
    for i in range(N):
        # 爆弾が届かない場合
        while index:
            if index[0][0] + 2*D < XH[i][0]:
                _,c = index.popleft()
                damage -= A * c
            else:
                break
        
        # 爆弾投下
        XH[i][1] -= damage

        # 生き残り
        if XH[i][1] > 0:
            count = ceil(XH[i][1]/A)
            damage += count * A
            index.append([XH[i][0],count])
            ans += count

    print(ans)

if __name__ == "__main__":
    main()
# Original solution
n,d,a=list(map(int,input().split()))
xh=[list(map(int,input().split())) for _ in range(n)]
xh.sort()

ans = 0
import queue
q=queue.Queue()


kaisuu = (xh[0][1] +a-1) // a
damege = kaisuu*a
ans += kaisuu
iti = xh[0][0] + 2*d
maedame = damege
skip =False
for i in range(1,n):
    while(iti < xh[i][0]):
        if skip:
            skip = False
            iti,damege = q.get()
            continue
        damege -= maedame
        if q.empty():
            skip =True
            break
        iti,maedame = q.get()
    if xh[i][1] - damege <= 0:
        continue
    kaisuu = (xh[i][1] - damege +a-1) // a
    damege += kaisuu*a
    q.put((xh[i][0] + 2*d, kaisuu*a))
    ans += kaisuu
print(ans)

# Optimized solution
n,d,a=list(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)
# Original solution
import sys
sys.setrecursionlimit(10 ** 7)

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

N, D, A = lr()
XH = [lr() for _ in range(N)]
XH.sort()

over = [N] * N # over[i]はi番目のモンスターを攻撃した時影響のないモンスターの最小値（最大はNで対象なし）
cur = 1
for i in range(N):
    while cur < N and XH[i][0] + D + D >= XH[cur][0]:
        cur += 1
    over[i] = cur

damage = 0 # 今までの累計のダメージ数　(影響のないダメージは引く)
reset = [0] * (N+1) # これ以降関係のないダメージ
answer = 0
for i in range(N):
    x, h = XH[i]
    damage -= reset[i]
    h -= damage
    if h > 0:
        time = (h+A-1)//A
        answer += time
        damage += A * time
        reset[over[i]] += A * time

print(answer)


# Optimized solution
import sys
sys.setrecursionlimit(10 ** 7)

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

def main():
    N, D, A = lr()
    XH = [lr() for _ in range(N)]
    XH.sort()

    over = [N] * N # over[i]はi番目のモンスターを攻撃した時影響のないモンスターの最小値（最大はNで対象なし）
    cur = 1
    for i in range(N):
        while cur < N and XH[i][0] + D + D >= XH[cur][0]:
            cur += 1
        over[i] = cur

    damage = 0 # 今までの累計のダメージ数　(影響のないダメージは引く)
    reset = [0] * (N+1) # これ以降関係のないダメージ
    answer = 0
    for i in range(N):
        x, h = XH[i]
        damage -= reset[i]
        h -= damage
        if h > 0:
            time = (h+A-1)//A
            answer += time
            damage += A * time
            reset[over[i]] += A * time

    print(answer)

if __name__ == "__main__":
    main()
# Original solution
N, D, a = [int(x) for x in input().split()]
XH = []
for _ in range(N):
    XH.append([int(x) for x in input().split()])
XH.sort()

#####segfunc######
def segfunc(x,y):
    return x + y

def init(init_val):
    #set_val
    for i in range(n):
        seg[i+num-1]=init_val[i]    
    #built
    for i in range(num-2,-1,-1) :
        seg[i]=segfunc(seg[2*i+1],seg[2*i+2]) 

def update(k,x):
    k += num-1
    seg[k] = x
    while k:
        k = (k-1)//2
        seg[k] = segfunc(seg[k*2+1],seg[k*2+2])

def query(p,q):
    if q<=p:
        return ide_ele
    p += num-1
    q += num-2
    res=ide_ele
    while q-p>1:
        if p&1 == 0:
            res = segfunc(res,seg[p])
        if q&1 == 1:
            res = segfunc(res,seg[q])
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res = segfunc(res,seg[p])
    else:
        res = segfunc(segfunc(res,seg[p]),seg[q])
    return res

#入力
n = N
A = [0] * N

#####単位元######
ide_ele = 0

#num:n以上の最小の2のべき乗
num =2**(n-1).bit_length()
seg=[ide_ele]*2*num

#init
init(A)

import bisect

X = []
H = []
for i in XH:
    X.append(i[0])
    H.append(i[1])
ans = 0
for i in range(N):
    x, h = X[i], H[i]
    idx_left = bisect.bisect_left(X, x - 2 * D)
    idx_right = bisect.bisect_right(X, x + 2 * D)
    if query(idx_left, idx_right) < h:
        h -= query(idx_left, idx_right)
        cnt = h // a
        if h % a != 0:
            cnt += 1
        ans += cnt
        update(i, a * cnt)
print(ans)
        


# Optimized solution
import sys
input = sys.stdin.readline

N, D, a = [int(x) for x in input().split()]
XH = []
for _ in range(N):
    XH.append([int(x) for x in input().split()])
XH.sort()

#####segfunc######
def segfunc(x,y):
    return x + y

def init(init_val):
    #set_val
    for i in range(n):
        seg[i+num-1]=init_val[i]    
    #built
    for i in range(num-2,-1,-1) :
        seg[i]=segfunc(seg[2*i+1],seg[2*i+2]) 

def update(k,x):
    k += num-1
    seg[k] = x
    while k:
        k = (k-1)//2
        seg[k] = segfunc(seg[k*2+1],seg[k*2+2])

def query(p,q):
    if q<=p:
        return ide_ele
    p += num-1
    q += num-2
    res=ide_ele
    while q-p>1:
        if p&1 == 0:
            res = segfunc(res,seg[p])
        if q&1 == 1:
            res = segfunc(res,seg[q])
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res = segfunc(res,seg[p])
    else:
        res = segfunc(segfunc(res,seg[p]),seg[q])
    return res

#入力
n = N
A = [0] * N

#####単位元######
ide_ele = 0

#num:n以上の最小の2のべき乗
num =2**(n-1).bit_length()
seg=[ide_ele]*2*num

#init
init(A)

import bisect

X = []
H = []
for i in XH:
    X.append(i[0])
    H.append(i[1])
ans = 0
for i in range(N):
    x, h = X[i], H[i]
    idx_left = bisect.bisect_left(X, x - 2 * D)
    idx_right = bisect.bisect_right(X, x + 2 * D)
    tmp = query(idx_left, idx_right)
    if tmp < h:
        h -= tmp
        cnt = h // a + int(h % a != 0)
        ans += cnt
        update(i, a * cnt)
print(ans)
# Original solution
import sys
input = sys.stdin.readline

N, D, a = [int(x) for x in input().split()]
XH = []
for _ in range(N):
    XH.append([int(x) for x in input().split()])
XH.sort()

#####segfunc######
def segfunc(x,y):
    return x + y

def init(init_val):
    #set_val
    for i in range(n):
        seg[i+num-1]=init_val[i]    
    #built
    for i in range(num-2,-1,-1) :
        seg[i]=segfunc(seg[2*i+1],seg[2*i+2]) 

def update(k,x):
    k += num-1
    seg[k] = x
    while k:
        k = (k-1)//2
        seg[k] = segfunc(seg[k*2+1],seg[k*2+2])

def query(p,q):
    if q<=p:
        return ide_ele
    p += num-1
    q += num-2
    res=ide_ele
    while q-p>1:
        if p&1 == 0:
            res = segfunc(res,seg[p])
        if q&1 == 1:
            res = segfunc(res,seg[q])
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res = segfunc(res,seg[p])
    else:
        res = segfunc(segfunc(res,seg[p]),seg[q])
    return res

#入力
n = N
A = [0] * N

#####単位元######
ide_ele = 0

#num:n以上の最小の2のべき乗
num =2**(n-1).bit_length()
seg=[ide_ele]*2*num

#init
init(A)

import bisect

X = []
H = []
for i in XH:
    X.append(i[0])
    H.append(i[1])
ans = 0
for i in range(N):
    x, h = X[i], H[i]
    idx_left = bisect.bisect_left(X, x - 2 * D)
    idx_right = bisect.bisect_right(X, x + 2 * D)
    tmp = query(idx_left, idx_right)
    if tmp < h:
        h -= tmp
        cnt = h // a + int(h % a != 0)
        ans += cnt
        update(i, a * cnt)
print(ans)
        


# Optimized solution
import sys
input = sys.stdin.readline

N, D, a = [int(x) for x in input().split()]
XH = []
for _ in range(N):
    XH.append([int(x) for x in input().split()])
XH.sort()

#####segfunc######
def segfunc(x,y):
    return x + y

def init(init_val):
    #set_val
    for i in range(n):
        seg[i+num-1]=init_val[i]    
    #built
    for i in range(num-2,-1,-1) :
        seg[i]=segfunc(seg[2*i+1],seg[2*i+2]) 

def update(k,x):
    k += num-1
    seg[k] = x
    while k:
        k = (k-1)//2
        seg[k] = segfunc(seg[k*2+1],seg[k*2+2])

def query(p,q):
    if q<=p:
        return ide_ele
    p += num-1
    q += num-2
    res=ide_ele
    while q-p>1:
        if p&1 == 0:
            res = segfunc(res,seg[p])
        if q&1 == 1:
            res = segfunc(res,seg[q])
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res = segfunc(res,seg[p])
    else:
        res = segfunc(segfunc(res,seg[p]),seg[q])
    return res

#入力
n = N
A = [0] * N

#####単位元######
ide_ele = 0

#num:n以上の最小の2のべき乗
num =2**(n-1).bit_length()
seg=[ide_ele]*2*num

#init
init(A)

import bisect

X = []
H = []
for i in XH:
    X.append(i[0])
    H.append(i[1])
ans = 0
for i in range(N):
    x, h = X[i], H[i]
    idx_left = bisect.bisect_left(X, x - 2 * D)
    idx_right = i
    tmp = query(idx_left, idx_right)
    if tmp < h:
        h -= tmp
        cnt = h // a + int(h % a != 0)
        ans += cnt
        update(i, a * cnt)
print(ans)
# Original solution
from collections import deque
import sys

input = sys.stdin.buffer.readline
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))

n, d, a = MAP()
xh = [LIST() for i in range(n)]

xh = sorted(xh, key=lambda x:(x[0]))
q = deque()
ca = 0
cnt = 0
for i in range(n):
    cx, ch = xh[i][0], xh[i][1]
    
    while q and q[0][0] < cx:
        qx, qa = q.popleft()
        ca -= qa
    
    if ch - ca <= 0:
        continue
    
    cn = (ch - ca + a - 1) // a
    cnt += cn
    ca += cn * a
    q.append([cx+2*d, cn*a])
    
print(cnt)

# Optimized solution
from collections import deque
import sys

input = sys.stdin.buffer.readline
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))

n, d, a = MAP()
monster = {}
x = []
for i in range(n):
    xx, hh = MAP()
    monster[xx] = hh
    x.append(xx)
x.sort()

q = deque()
ca = 0
cnt = 0
for i in range(n):
    cx, ch = x[i], monster[x[i]]
    
    while q and q[0][0] < cx:
        qx, qa = q.popleft()
        ca -= qa
    
    if ch - ca <= 0:
        continue
    
    cn = (ch - ca + a - 1) // a
    cnt += cn
    ca += cn * a
    q.append([cx+2*d, cn*a])
    
print(cnt)
# Original solution
N,D,A=list(map(int,input().split()))
L=[]
for i in range(N):
    x,h=list(map(int,input().split()))
    L.append([x,h])
L.sort()

import math

ans=0
S=0
P=0
RL=[10**10]
RC=[0]
cnt=0
for i in range(N):
    while RL[P]<L[i][0]:
        cnt+=RC[P]
        P+=1
    if L[i][1]-S+cnt>0:
        ans+=math.ceil((L[i][1]-S+cnt)/A)
        RL=RL[:len(RL)-1]
        RC=RC[:len(RC)-1]
        RL+=[L[i][0]+2*D]+[10**10]
        RC+=[math.ceil((L[i][1]-S+cnt)/A)*A]+[0]
        S+=math.ceil((L[i][1]-S+cnt)/A)*A
    #print(i,ans,P)
print(ans)

# Optimized solution
import sys
input=sys.stdin.readline

N,D,A=list(map(int,input().split()))
L=[]
for i in range(N):
    x,h=list(map(int,input().split()))
    L.append([x,h])
L.sort()

import math

ans=0
S=0
P=0
RL=[0]
RC=[0]
cnt=0
for i in range(N):
    for j in range(P,len(RL)):
        if RL[P]<L[i][0]:
            cnt+=RC[P]
            P+=1
        else:
            break
    if L[i][1]-S+cnt>0:
        ans+=math.ceil((L[i][1]-S+cnt)/A)
        
        RL+=[L[i][0]+2*D]
        RC+=[math.ceil((L[i][1]-S+cnt)/A)*A]
        S+=math.ceil((L[i][1]-S+cnt)/A)*A
    #print(i,ans,P,RL,RC,S,cnt)
print(ans)
# Original solution
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])
ans = 0
k = 0
while k < len(monster):
  if monster[k][1] > 0:
    nowx = monster[k][0]
    damage = ((monster[k][1]-0.1)//A)*A + A
    ans += int((monster[k][1]-0.1)//A + 1)
    j = 0 + k
    nextk = N
    while(j +1 < len(monster)):
      j += 1
      if monster[j][0] <= nowx + 2*D:
        monster[j][1] -= damage
        if monster[j][1] > 0:
          nextk = min(j, nextk)
          continue
      else:
        nextk = min(nextk, j)
        break
    k = nextk

print(ans)

# Optimized solution
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
"""
k = 0
while k < len(monster):
  if monster[k][1] > 0:
    nowx = monster[k][0]
    damage = monster[k][1]
    ans += monster[k][1]
    j = 0 + k
    nextk = N
    while(j +1 < len(monster)):
      j += 1
      if monster[j][0] <= nowx + 2*D:
        monster[j][1] -= damage
        if monster[j][1] > 0:
          nextk = min(j, nextk)
          continue
      else:
        nextk = min(nextk, j)
        break
    k = nextk
"""
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)