CodeEff/ECCO huggingface dataset:
# Original solution
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)


# Optimized solution
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)
# Original solution
from bisect import bisect_right
n,d,a=list(map(int,input().split()))
xh=[list(map(int,input().split()))for _ in range(n)]
xh.sort()
x=[]
h=[]
for xx,hh in xh:
  x.append(xx)
  h.append(hh)

not_imos=[0]*(n+1)
atk_n=0
ans=0
for i in range(n):
  atk_n-=not_imos[i]
  h[i]-=atk_n*a
  if h[i]<0:h[i]=0
  atk_i=0--h[i]//a
  ans+=atk_i
  atk_n+=atk_i
  not_imos[bisect_right(x,x[i]+d*2)]+=atk_i
print(ans)

# Optimized solution
n,d,a=list(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)
# Original solution
from operator import itemgetter
import bisect
N, D, A = list(map(int, input().split()))
enemies = sorted([list(map(int, input().split())) for i in range(N)], key=itemgetter(0))
d_enemy = [enemy[0] for enemy in enemies]
b_left = bisect.bisect_left
logs = []
ans = 0
for i, enemy in enumerate(enemies):
    X, hp = enemy
    count = 0
    for log in logs:
        start, end, log_count = log
        if start <= X <= end:
            count += log_count
    hp -= count * A
    if hp > 0:
        attack_num = (hp + A-1) // A
        logs.append((X, X+2*D, attack_num))
        ans += attack_num
print(ans)





# Optimized solution
from operator import itemgetter
import bisect
N, D, A = list(map(int, input().split()))
enemies = sorted([list(map(int, input().split())) for i in range(N)], key=itemgetter(0))
d_enemy = [enemy[0] for enemy in enemies]
b_left = bisect.bisect_left
logs = []
logs_S = [0, ]
ans = 0
for i, enemy in enumerate(enemies):
    X, hp = enemy

    start_i = b_left(logs, X-2*D)
    count = logs_S[-1] - logs_S[start_i]

    hp -= count * A
    if hp > 0:
        attack_num = (hp + A-1) // A
        logs.append(X)
        logs_S.append(logs_S[-1]+attack_num)
        ans += attack_num
print(ans)
# Original solution
import sys

readline = sys.stdin.readline
MOD = 10 ** 9 + 7
INF = float('INF')
sys.setrecursionlimit(10 ** 5)


def main():
    n, d, a = list(map(int, readline().split()))
    xh = [list(map(int, readline().split())) for _ in range(n)]

    from operator import itemgetter
    import bisect

    xh.sort(key=itemgetter(0))
    coordinate = [xh[i][0] for i in range(n)]
    hp = [xh[i][1] for i in range(n)]

    ans = 0

    for i in range(n):
        x = coordinate[i]
        h = hp[i]

        if h > 0:
            num = (h + a - 1) // a
            ans += num
            dmg = a * num
            range_left = x
            range_right = x + 2 * d
            index_left = bisect.bisect_left(coordinate, range_left)
            index_right = bisect.bisect_right(coordinate, range_right)
            for j in range(index_left, index_right):
               hp[j] -= dmg

    print(ans)


if __name__ == '__main__':
    main()


# Optimized solution
import sys

readline = sys.stdin.readline
MOD = 10 ** 9 + 7
INF = float('INF')
sys.setrecursionlimit(10 ** 5)


def main():
    n, d, a = list(map(int, readline().split()))
    xh = [list(map(int, readline().split())) for _ in range(n)]

    from operator import itemgetter, add
    import bisect

    xh.sort(key=itemgetter(0))
    coordinate = [xh[i][0] for i in range(n)]
    hp = [xh[i][1] for i in range(n)]

    ans = 0
    dmg_cur = 0
    dmg_cum = [0] * (n + 1)

    for i in range(n):
        x = coordinate[i]
        h = hp[i]

        dmg_cur += dmg_cum[i]
        h -= dmg_cur

        if h > 0:
            num = (h + a - 1) // a
            ans += num
            dmg = a * num
            dmg_cur += dmg
            range_left = x
            range_right = x + 2 * d
            index_right = bisect.bisect_right(coordinate, range_right)
            dmg_cum[index_right] -= dmg
    print(ans)


if __name__ == '__main__':
    main()
# Original solution
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees, log2, gcd
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left, insort, insort_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))
def TUPLE(): return tuple(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 
#mod = 998244353
from decimal import *
#import numpy as np
#decimal.getcontext().prec = 10

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 0 < H:
		n = -(-H//A)
		ans += n
		d = A*n
		damage[i] += d
		damage[right[i]] -= d
print(ans)


# Optimized solution
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees, log2, gcd
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left, insort, insort_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))
def TUPLE(): return tuple(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 
#mod = 998244353
from decimal import *
#import numpy as np
#decimal.getcontext().prec = 10

N, D, A = MAP()
XH = [LIST() for _ in range(N)]

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

X = [XH[i][0] for i in range(N)]
H = [XH[i][1] for i in range(N)]

ans = 0
imos = [0]*(N+1)
tmp = 0
for i in range(N):
	x, h = XH[i]
	tmp += imos[i]
	left = h-tmp
	if 0 < left:
		cnt = -(-left//A)
		damage = A*cnt
		idx = bisect(X, x+2*D)
		tmp += damage
		imos[idx] -= damage
		ans += cnt

print(ans)
# Original solution
n, d, a = list(map(int, input().split()))
xh = []
for i in range(n):
    xi, hi = list(map(int, input().split()))
    xh.append([xi, hi])

xh.sort(key=lambda x: x[0])
x, h = [], []
for i in range(n):
    x.append(xh[i][0])
    h.append(xh[i][1])

cnt = 0
for i in range(n):
    xi, hi = x[i], h[i]
    if hi == 0:
        continue
    else:
        num = (hi+a-1)//a
        cnt += num
    point = xi + 2*d
    left = i
    right = n
    while left+1 < right:
        mid = (left+right)//2
        if x[mid] <= point:
            left = mid
        else:
            right = mid
    for j in range(i, left+1):
        h[j] = max(0, h[j]-num*a)
print(cnt)

# Optimized solution
n, d, a = list(map(int, input().split()))
xh = []
for i in range(n):
    xi, hi = list(map(int, input().split()))
    xh.append([xi, hi])

xh.sort(key=lambda x: x[0])
x, h = [], []
for i in range(n):
    x.append(xh[i][0])
    h.append(xh[i][1])

cnt = 0
dmg = [0 for i in range(n+1)]
for i in range(n):
    xi, hi = x[i], h[i]
    dmg[i] += dmg[i-1]
    hi -= dmg[i]
    if hi <= 0:
        continue
    else:
        num = (hi+a-1)//a
        cnt += num
    point = xi + 2*d
    left = i
    right = n
    while left+1 < right:
        mid = (left+right)//2
        if x[mid] <= point:
            left = mid
        else:
            right = mid
    dmg[i] += num*a
    dmg[left+1] -= num*a
print(cnt)
# Original solution
class SegmentTree:
    def __init__(self, N, id, fun):#id:単位元
        self.N0 = 2**(N-1).bit_length()
        self.id = id
        self.data = [self.id]*(2*self.N0)
        self.fun = fun
 
    def update(self, l, r, val):#[l, r)をvalで更新
        l += self.N0
        r += self.N0
        while l < r:
            if l & 1 :
                self.data[l] = self.fun(self.data[l], val)
                l += 1
            if r & 1:
                self.data[r-1] = self.fun(self.data[r-1], val)
                r -= 1
            l //= 2
            r //= 2
 
    def query(self, i):
        i += self.N0
        ret = self.data[i]
        while i > 0 :
            i //= 2
            ret = self.fun(ret, self.data[i])
        return ret
N, D, A = list(map(int, input().split()))
XH = [list(map(int, input().split())) for _ in range(N)]
XH.sort()
S = SegmentTree(N, 0, lambda x, y:x+y)
ans = 0
from bisect import bisect
for i in range(N):
    x, h = XH[i]
    c = S.query(i)
    h-=c
    if h<=0:
        continue
    n = ((h-1)//A+1)
    j = bisect(XH, [x+D*2+1, -1])
    S.update(i, j, n*A)
    ans+=n
print(ans)
    





# Optimized solution

N, D, A = list(map(int, input().split()))
XH = [list(map(int, input().split())) for _ in range(N)]
XH.sort()
X = [XH[i][0] for i in range(N)]
ans = 0
res = 0
from bisect import bisect_left
cnt = [0]*(N+1)
for i in range(N):
    x, h = XH[i]
    res-=cnt[i]
    h-=res
    if h<=0:
        continue
    n = ((h-1)//A+1)
    j = bisect_left(X, x+D*2+1)
    cnt[j]+=n*A
    res += n*A
    ans+=n
print(ans)
# Original solution
def main():
    N, D, A = (int(i) for i in input().split())
    P = [[int(i) for i in input().split()] for j in range(N)]
    P.sort()
    X = [x[0] for x in P]
    H = [h[1] for h in P]
    diff = [H[0]] + [H[i+1] - H[i] for i in range(N-1)]
    BIT = [0] * (N+1)

    def BIT_query(idx):
        """ A1 ~ Aiまでの和(1-index) """
        res_sum = 0
        while idx > 0:
            res_sum += BIT[idx]
            idx -= idx & -idx
        return res_sum

    def BIT_update(idx, x):
        """ Aiにxを加算(1-index) """
        while idx <= N:
            BIT[idx] += x
            idx += idx & -idx
        return

    def BIT_init(A):
        for i, e in enumerate(A):
            BIT_update(i+1, e)

    BIT_init(diff)
    from bisect import bisect_right
    ans = 0
    for left in range(N):
        x = P[left][0]
        h = BIT_query(left+1)
        if h > 0:
            cur = (h + A - 1) // A
            damage = cur * A
            BIT_update(left+1, -damage)
            right = bisect_right(X, x + 2*D)
            BIT_update(right+1, damage)
            ans += cur
    print(ans)


if __name__ == '__main__':
    main()


# Optimized solution
def main():
    N, D, A = (int(i) for i in input().split())
    P = [[int(i) for i in input().split()] for j in range(N)]
    P.sort()
    X = [x[0] for x in P]
    H = [h[1] for h in P]
    diff = [H[0]] + [H[i+1] - H[i] for i in range(N-1)]
    BIT = [0] * (N+1)

    def BIT_query(idx):
        """ A1 ~ Aiまでの和(1-index) """
        res_sum = 0
        while idx > 0:
            res_sum += BIT[idx]
            idx -= idx & -idx
        return res_sum

    def BIT_update(idx, x):
        """ Aiにxを加算(1-index) """
        while idx <= N:
            BIT[idx] += x
            idx += idx & -idx
        return

    def BIT_init(A):
        for i, e in enumerate(A):
            BIT_update(i+1, e)

    BIT_init(diff)
    ans = 0
    right = 0
    for left in range(N):
        x = P[left][0]
        h = BIT_query(left+1)
        while right < N and P[right][0] <= x + 2*D:
            right += 1
        if h > 0:
            cur = (h + A - 1) // A
            damage = cur * A
            BIT_update(left+1, -damage)
            BIT_update(right+1, damage)
            ans += cur
    print(ans)


if __name__ == '__main__':
    main()
# Original solution
def main():
    N, D, A = list(map(int, input().split()))
    XH = []
    for i in range(N):
        x, h = list(map(int, input().split()))
        h = (h + (A - 1)) // A
        XH.append([x, h])

    XH.sort()
    result = 0
    for i in range(N):
        x, h = XH[i]
        if h < 0:
            continue
        result += h
        for j in range(i + 1, N):
            if XH[j][0] > x + 2 * D:
                break
            XH[j][1] -= h
    print(result)
main()


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

XH.sort()
q = []
t = 0
result = 0
for x, h in XH:
    while True:
        if len(q) == 0:
            break
        if x <= q[0][0]:
            break
        t -= q[0][1]
        q.pop(0)
    h -= t
    if h < 0:
        continue
    c = (h + A - 1) // A
    result += c
    t += c * A
    q.append((x + 2 * D, c * A))
print(result)
# Original solution
N, D, A = list(map(int, input().split()))
XH = [list(map(int, input().split())) for _ in range(N)]

XH.sort()
q = []
t = 0
result = 0
for x, h in XH:
    while True:
        if len(q) == 0:
            break
        if x <= q[0][0]:
            break
        t -= q[0][1]
        q.pop(0)
    h -= t
    if h < 0:
        continue
    c = (h + A - 1) // A
    result += c
    t += c * A
    q.append((x + 2 * D, c * A))
print(result)


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

XH.sort()
q = []
t = 0
result = 0
for x, h in XH:
    while q:
        if x <= q[0][0]:
            break
        t -= q[0][1]
        q.pop(0)
    h -= t
    if h < 0:
        continue
    c = (h + A - 1) // A
    result += c
    t += c * A
    q.append((x + 2 * D, c * A))
print(result)
# Original solution
import bisect

N,D,A = list(map(int,input().split()))
mons = []
X = []; H = []
need = [0]*N

for _ in range(N):
    x,h = list(map(int,input().split()))
    mons.append([x,h])
mons = sorted(mons)

for i in range(N):
    X.append(mons[i][0]); H.append(mons[i][1])
    need[i] = mons[i][1] // A
    if mons[i][1] % A != 0: need[i] += 1

eliminated = 0
target = 0
ans = 0
while eliminated < N:
    for i in range(target,N):
        if need[i] > 0:
            target = i
            break
        else:
            eliminated += 1
    need_bomb = need[target]
    bomb_range = bisect.bisect_right(X,X[target] + 2*D)
    for i in range(target,bomb_range):
        need[i] -= need_bomb
    ans += need_bomb
print(ans)

# Optimized solution
import bisect

N,D,A = list(map(int,input().split()))
mons = []; X = []; need = [0]*N; bomb_range = []

for _ in range(N):
    x,h = list(map(int,input().split()))
    mons.append([x,h])
mons = sorted(mons)

for i in range(N):
    X.append(mons[i][0])
    need[i] = mons[i][1] // A
    if mons[i][1] % A != 0: need[i] += 1

for i in range(N):
    bomb_range.append(bisect.bisect_right(X,X[i] + 2*D))

if N == 1:
    ans = need[0]
else:
    # imos setting
    imos = [0]*(N+1)
    imos[0] = need[0]
    imos[bomb_range[0]] = - need[0]
    #
    ans = need[0]
    for i in range(1,N):
        imos[i] += imos[i-1]
        bomb = need[i] - imos[i]
        if bomb > 0:
            ans += bomb
            imos[i] += bomb
            imos[bomb_range[i]] -= bomb
        else:
            continue

print(ans)
# Original solution
from collections import deque


n, d, a = list(map(int, input().split()))
monsters = []
for _ in range(n):
    pos, hp = list(map(int, input().split()))
    monsters.append([pos, hp])

monsters.sort()

bomb_area = deque([])
bomb_power = deque([])
total_damage = 0
ans = 0
for pos, hp in monsters:
    while bomb_area:
        area = bomb_area[0]
        if area < pos:
            bomb_area.popleft()
            power = bomb_power.popleft()
            total_damage -= power
        else:
            break
    if hp <= total_damage:
        continue
    else:
        count = (hp-total_damage + a-1) // a
        ans += count
        power = a * count
        total_damage += power
        bomb_area.append(pos+2*d)
        bomb_power.append(power)

print(ans)

# Optimized solution
from collections import deque
import sys
input = sys.stdin.readline


n, d, a = list(map(int, input().split()))
monsters = []
for _ in range(n):
    pos, hp = list(map(int, input().split()))
    monsters.append([pos, hp])

monsters.sort()

bomb_area = deque([])
bomb_power = deque([])
total_damage = 0
ans = 0
for pos, hp in monsters:
    while bomb_area:
        area = bomb_area[0]
        if area < pos:
            bomb_area.popleft()
            power = bomb_power.popleft()
            total_damage -= power
        else:
            break
    if hp <= total_damage:
        continue
    else:
        count = (hp-total_damage + a-1) // a
        ans += count
        power = a * count
        total_damage += power
        bomb_area.append(pos+2*d)
        bomb_power.append(power)

print(ans)
# Original solution
import sys
from collections import deque

def I(): return int(sys.stdin.readline())
def MI(): return list(map(int, sys.stdin.readline().split()))
def LMI(): return list(map(int, sys.stdin.readline().split()))
MOD = 10 ** 9 + 7


N, D, A = MI()
monsters = list()
for i in range(N):
    x, h = MI()
    monsters.append((x, (h + A - 1) // A))
monsters.sort()

ans = 0
for i, (x, h) in enumerate(monsters):
    if h > 0:
        ans += h
        j = i + 1
        while j < N:
            xj, hj = monsters[j]
            if xj > x + 2 * D:
                break
            monsters[j] = (xj, max(0, hj - h))
            j += 1
print(ans)

# Optimized solution
import sys
from bisect import bisect_right

def I(): return int(sys.stdin.readline())
def MI(): return list(map(int, sys.stdin.readline().split()))
def LMI(): return list(map(int, sys.stdin.readline().split()))
MOD = 10 ** 9 + 7


N, D, A = MI()
monsters = list()
for i in range(N):
    x, h = MI()
    monsters.append((x, (h + A - 1) // A))
monsters.sort()

X = [x for x, h in monsters]
ub = [0] * N
for i, x in enumerate(X):
    ub[i] = bisect_right(X, x + 2 * D)

dmg = [0] * N
accum = 0
ans = 0
for i, (x, h) in enumerate(monsters):
    h = h - max(0, accum + dmg[i])
    if h > 0:
        ans += h
        dmg[i] += h
        if ub[i] < N:
            dmg[ub[i]] -= h
    accum += dmg[i]
print(ans)
# Original solution
#!/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)

if __name__ == "__main__":
    main()


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

if __name__ == "__main__":
    main()
# Original solution
import sys
import math
import bisect

input = sys.stdin.readline
ceil = math.ceil
rbisect=bisect.bisect_right
def main():
    n,d,a = list(map(int,input().split()))
    mon = []
    for i in range(n):
        x,h = list(map(int,input().split()))
        mon.append((x,h))
    mon.sort()
    keys = [ls[0] for ls in mon] #bisect用の配列

    damage = [0]*(n+1)
    ans = 0
    for i in range(n):
        x,h = mon[i]
        res = h-damage[i]
        if res>0:##体力が残ってたら
            c = ceil(res/a)
            ans+=c
            idx = rbisect(keys[i:],x+2*d)-1 ##爆風が届くぎりぎりの位置
            if idx==-1:continue
            damage[i] +=a*c
            damage[i+idx+1] -=a*c
        damage[i+1] += damage[i]
    print(ans)
if __name__=="__main__":
    main()


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

def main():
    def isok(z,val):##適宜変更
        return (z-val<=2*d)
    def bisect(ls,val): ##valの関数isok(x,val)がTrueとなる一番右のindex を返す 全部Falseなら-1
        ok = -1
        ng = len(ls)
        idx = (ok+ng)//2
        while ng-ok>1:
            num = ls[idx]
            if isok(num,val):
                ok = idx
            else:
                ng = idx
            idx = (ok+ng)//2
        return ok ##一番右のTrueのindex  Trueの個数はok+1こ

    n,d,a = list(map(int,input().split()))
    mon = []
    for i in range(n):
        x,h = list(map(int,input().split()))
        mon.append((x,h))
    mon.sort()
    keys = [ls[0] for ls in mon] #bisect用の配列

    damage = [0]*(n+1)
    ans = 0
    for i in range(n):
        x,h = mon[i]
        res = h-damage[i]
        if res>0:##体力が残ってたら
            c = ceil(res/a)
            ans+=c
            idx = bisect(keys,x) ##爆風が届くぎりぎりの位置
            if idx==-1:continue
            damage[i] +=a*c
            damage[idx+1] -=a*c
        damage[i+1] += damage[i]
    print(ans)
if __name__=="__main__":
    main()
# Original solution
N,D,A=[int(x) for x in input().split()]
xh = [[int(x) for x in input().split()] for _ in range(N)]
xh = sorted(xh)
r=0
l=0
ans = 0
mi = 10**9
for l in range(N):
  if xh[l][1]==0:
    #print(l)
    continue
  la = (xh[l][1]+A-1)//A
  xh[l][1]=0
  r=l
  for _ in range(N):
    if l<N and r<N and 2*D>xh[r][0]-xh[l][0]:
      if 2*D<abs(xh[l][0]-xh[min(r+1,N-1)][0]):
        break
      else:
        r+=1
        if r<N:
          xh[r][1]=max(0,xh[r][1]-la*A)
    else:
      break
  ans +=la
  if r==l:
    r+=1
print(ans)


# Optimized solution
N,D,A=[int(x) for x in input().split()]
xh = [[int(x) for x in input().split()] for _ in range(N)]
xh = sorted(xh)
r=0
l=0
ans = 0
mi = 10**9
d = [0]*(N+1)
for l in range(N):
  if d[l]<xh[l][1]:
    la = (xh[l][1]-d[l]+A-1)//A
    for _ in range(N):
      if l<N and r<N and 2*D>=xh[r][0]-xh[l][0]:
        r+=1
      else:
        break
    ans += la
    d[l]+=la*A
    d[r]-=la*A
  d[l+1]+=d[l]
print(ans)