CodeEff/ECCO huggingface dataset:
# Original solution
from bisect import bisect_right
def getVal(i):  # get value of node (i,i)
    v = T[(i,i)][0]
    cur = (i,i)
    cur = T[cur][1]
    while cur[0]>=0:
        v += T[cur][0]
        cur = T[cur][1]
    return v
def udT(i,j,x,node):  # add x between [i,j] where current node is given
    l,r = node[0],node[1]
    if i<=l and r<=j:
        T[node][0] += x
    elif i>r or j<l:
        return
    else:
        udT(i,j,x,T[node][2])
        udT(i,j,x,T[node][3])
N,D,A = list(map(int,input().split()))
X = sorted([list(map(int,input().split())) for _ in range(N)],key=lambda x:x[0])
n = 0
m = N
while m>0:
    m = m//2
    n += 1
if N==2**(n-1):
    n -= 1
for i in range(N,2**n):  # fill in the remainder of N
    X.append([X[-1][0]+1,0])
# Construction of Tree
Y = [X[i][0] for i in range(N)]  # Tree structure
if N>1:
    T = {(i,i):[X[i][1],(i,i+1) if i%2==0 else (i-1,i),(-1,-1),(-1,-1)] for i in range(2**n)}  # T[node] = [value,parent,left_child,right_child]
else: # N==1
    T = {(i,i):[X[i][1],(-1,-1),(-1,-1),(-1,-1)] for i in range(2**n)}  # T[node] = [value,parent,left_child,right_child]
for h in range(n):
    for i in range(2**h):
        d = 2**(n-h)  # interval length of each node
        if h==0:
            T[(i*d,(i+1)*d-1)] = [0,(-1,-1),(i*d,i*d+d//2-1),((i+1)*d-d//2,(i+1)*d-1)]
        else:
            T[(i*d,(i+1)*d-1)] = [0,(i*d,i*d+2*d-1) if (i*d)%2**(n-h+1)==0 else ((i+1)*d-2*d,(i+1)*d-1),(i*d,i*d+d//2-1),((i+1)*d-d//2,(i+1)*d-1)]
cnt = 0
cur = 0
while cur<N:
    x = Y[cur]
    v = getVal(cur)
    if v%A==0:
        k = v//A
    else:
        k = v//A+1
    ind = bisect_right(Y,x+2*D)
    udT(cur,ind-1,-k*A,(0,2**n-1))
    cnt += k
    flag = 0
    for i in range(cur+1,N):
        if getVal(i)>0:
            cur = i
            flag = 1
            break
    if flag==0:
        cur = N
print(cnt)

# Optimized solution
from bisect import bisect_right
N,D,A = list(map(int,input().split()))
X = sorted([list(map(int,input().split())) for _ in range(N)],key=lambda x:x[0])
B = [0 for _ in range(N+1)]
cnt = 0
cur = 0
delta = 0
flag = 0
while cur<N:
    x = X[cur][0]
    h = X[cur][1]+delta
    if h%A==0:
        n = h//A
    else:
        n = h//A+1
    ind = bisect_right(X,[x+2*D,10**9+1])
    B[cur] += -n*A
    B[ind] += n*A
    cnt += n
    flag = 0
    for i in range(cur,N):
        delta += B[i]
        B[i] = 0
        if X[i][1]+delta>0:
            cur = i
            flag = 1
            break
    if flag==0:
        cur = N
print(cnt)
# Original solution
import math

def make_tree(n):
    i = 2
    while True:
        if i >= n * 2:
            tree = [0] * i
            break
        else:
            i *= 2
    return tree

def get(i):
    i += len(tree) // 2
    ans = 0
    while True:
        if i == 0:
            break
        ans += tree[i] 
        i //= 2
    return ans

def update(s, t, x):
    s += len(tree) // 2
    t += len(tree) // 2
    while True:
        if s > t:
            break
        if s % 2 == 0:
            s //= 2
        else:
            tree[s] += x
            s = (s + 1) // 2
        if t % 2 == 1:
            t //= 2
        else:
            tree[t] += x
            t = (t - 1) // 2
    return

n, d, a = list(map(int, input().split()))
s = [list(map(int, input().split())) for _ in range(n)]
s.sort()
tree = make_tree(n)
for i in range(n):
    update(i, i, s[i][1])
y = [n - 1] * n
j = 0
for i in range(n):
    if j == n:
        break
    while True:
        if j == n:
            break
        if s[i][0] + 2 * d >= s[j][0]:
            j += 1
        else:
            y[i] = j - 1
            break
ans = 0
for i in range(n):
    h = get(i)
    if h > 0:
        c = math.ceil(h / a)
        ans += c
        update(i, y[i], -1 * a * c)
print(ans)

# Optimized solution
import math

def make_tree(n):
    i = 2
    while True:
        if i >= n * 2:
            tree = [0] * i
            break
        else:
            i *= 2
    return tree

def get(i):
    i += len(tree) // 2
    ans = 0
    while True:
        if i == 0:
            break
        ans += tree[i] 
        i //= 2
    return ans

def update(s, t, x):
    s += len(tree) // 2
    t += len(tree) // 2
    while True:
        if s > t:
            break
        if s % 2 == 0:
            s //= 2
        else:
            tree[s] += x
            s = (s + 1) // 2
        if t % 2 == 1:
            t //= 2
        else:
            tree[t] += x
            t = (t - 1) // 2
    return

n, d, a = list(map(int, input().split()))
s = [list(map(int, input().split())) for _ in range(n)]
s.sort()
tree = make_tree(n)
l = len(tree)
for i in range(n):
    tree[i + l // 2] = s[i][1]
y = [n - 1] * n
j = 0
for i in range(n):
    if j == n:
        break
    while True:
        if j == n:
            break
        if s[i][0] + 2 * d >= s[j][0]:
            j += 1
        else:
            y[i] = j - 1
            break
ans = 0
for i in range(n):
    h = get(i)
    if h > 0:
        c = math.ceil(h / a)
        ans += c
        update(i, y[i], -1 * a * c)
print(ans)
# Original solution
N, D, A = list(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)

# Optimized solution
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()))
# Original solution
from collections import deque
import math
import bisect
n, d, a = list(map(int, input().split()))
data = []
x_point = []
for i in range(n):
    x,h = list(map(int, input().split()))
    data.append([x,h])
    x_point.append(x)
data.sort()
x_point.sort()
imos = [0] * (n+2)
ans = 0
for i in range(1,n+1):
    x, h = data[i-1]
    imos[i] += imos[i-1]
    index = bisect.bisect_right(x_point, x + 2*d)
    h -= imos[i]
    count = max(math.ceil(h/a), 0)
    ans += count
    imos[i] += count*a
    if index + 1 <= n:
        imos[index+1] -=count*a
print(ans)



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

N, D, A = list(map(int, input().split()))
M = []
for i in range(N):
  x, h = list(map(int, input().split()))
  M.append((x, -(-h//A)))
M.sort(key=lambda x: x[0])
X = list([x[0] for x in M])
H = list([x[1] for x in M])

dmg = [0] * (N+1)
ans = 0

for i in range(N):
  x, h = M[i]
  h = max(0, h - dmg[i])
  dmg[i] += h
  dmg[bisect_right(X, x + 2*D)] -= h
  dmg[i+1] += dmg[i]
  ans += h
print(ans)

# Optimized solution
from bisect import bisect_right

N, D, A = list(map(int, input().split()))
M = []
for i in range(N):
  x, h = list(map(int, input().split()))
  M.append((x, -(-h//A)))
M.sort(key=lambda x: x[0])
X = list([x[0] for x in M])
H = list([x[1] for x in M])

dmg = [0] * (N+1)
ans = 0

for i in range(N):
  x, h = M[i]
  h = max(0, h - dmg[i])
  dmg[bisect_right(X, x + 2*D)] -= h
  dmg[i+1] += dmg[i] + h
  ans += h
print(ans)
# Original solution
def main():
    from bisect import bisect
    def _add(data,k,x):
        while k<=N:
            data[k]+=x
            k+=k&-k
    def add(l,r,x):
        _add(data0,l,-x*(l-1))
        _add(data0,r,x*(r-1))
        _add(data1,l,x)
        _add(data1,r,-x)
    def _get(data,k):
        s=0
        while k:
            s+=data[k]
            k-=k&-k
        return s
    def query(l,r):
        return _get(data1,r-1)*(r-1)+_get(data0,r-1)-_get(data1,l-1)*(l-1)-_get(data0,l-1)
    N,d,a,*t=list(map(int,open(0).read().split()))
    data0=[0]*(N+1)
    data1=[0]*(N+1)
    z=sorted(zip(*[iter(t)]*2))
    y=[x for x,_ in z]
    c=0
    for i,(x,h)in enumerate(z,1):
        h-=query(i,i+1)
        t=0--max(0,h)//a
        j=bisect(y,x+d+d)
        add(1,j+1,t*a)
        c+=t
    print(c)
main()

# Optimized solution
from bisect import*
def _add(data,k,x):
    while k<=N:
        data[k]+=x
        k+=k&-k
def add(l,r,x):
    _add(data0,l,-x*(l-1))
    _add(data0,r,x*(r-1))
    _add(data1,l,x)
    _add(data1,r,-x)
def _get(data,k):
    s=0
    while k:
        s+=data[k]
        k-=k&-k
    return s
def query(l,r):
    return _get(data1,r-1)*(r-1)+_get(data0,r-1)-_get(data1,l-1)*(l-1)-_get(data0,l-1)
N,d,a,*t=list(map(int,open(0).read().split()))
data0=[0]*(N+1)
data1=[0]*(N+1)
z=sorted(zip(*[iter(t)]*2))
y=[x for x,_ in z]
c=0
for i,(x,h)in enumerate(z,1):
    h-=query(i,i+1)
    t=0--max(0,h)//a
    j=bisect(y,x+d+d)
    add(1,j+1,t*a)
    c+=t
print(c)
# Original solution
import sys
def input():
    return sys.stdin.readline()[:-1]

#import numpy as np
import math
from bisect import bisect

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 = [i[0] for i in xh]
h = [i[1] for i in xh]
#h_int = np.ceil(h/A)

cnt=0
for i in range(len(x)):
    if h[i]<=0: continue
    h_int =  math.ceil(h[i]/A)
    cnt+=h_int
    r = bisect(x, x[i]+2*D)
    for j in range(i+1, r):
      if j>N-1:break
      h[j] = h[j]-h_int*A

print((int(cnt)))


# Optimized solution
#import numpy as np
import math
from bisect import bisect

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 = [i[0] for i in xh]
h = [i[1] for i in xh]
#h_int = np.ceil(h/A)

cnt=0
damage=[0]*(N+1)

for i in range(len(x)):
    damage[i] += damage[i-1]
    h[i] -= damage[i]
    if h[i]<=0: continue
    h_int =  math.ceil(h[i]/A)
    cnt+=h_int
    damage[i]+=h_int*A
    r=bisect(x,x[i]+2*D)
    #print(damage[i])
    damage[r]-= A*h_int
    

print((int(cnt)))
# Original solution
from heapq import heappush, heappop

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

data = []
for _ in range(N):
	x, h = list(map(int, input().split()))
	heappush(data, (x, 0, h))

total = 0
height = 0
while data:
	x, type, h = heappop(data)
	if type == 0:
		if height < h:
			count = (h - height + A - 1) // A
			total += count
			height += count * A
			heappush(data, (x + D * 2, 1, count * A))
	else:
		height -= h

print(total)


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

data = []
for _ in range(N):
	data.append(tuple(map(int, input().split())))

data.sort()

queue = []
i = 0
j = 0
total = 0
height = 0
while i < N:
	if j >= len(queue) or data[i][0] <= queue[j][0]:
		x, h = data[i]
		i += 1
		if height < h:
			count = (h - height + A - 1) // A
			total += count
			height += count * A
			queue.append((x + D * 2, count * A))
	else:
		height -= queue[j][1]
		j += 1

print(total)
# Original solution
import math
from heapq import heappop, heappush
N, D, A = list(map(int, input().split()))
D *= 2
enemies = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    enemies.append((x, math.ceil(h / A)))
enemies.sort()

t = 0
ans = 0
attacks = []
attacksum = 0
for f in range(N):
    x, h = enemies[f]
    while attacks:
        if x > attacks[0][0]:
            ax, ad = heappop(attacks)
            attacksum -= ad
        else:
            break
    if h <= attacksum:
        continue
    damage = h - attacksum
    attacksum += damage
    ans += damage
    attacks.append((x + D, damage))

print(ans)

# Optimized solution
import math
from heapq import heappop, heappush
N, D, A = list(map(int, input().split()))
D *= 2
enemies = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    enemies.append((x, math.ceil(h / A)))
enemies.sort()

t = 0
ans = 0
attacks = []
attacksum = 0
for f in range(N):
    x, h = enemies[f]
    while attacks:
        if x > attacks[0][0]:
            ax, ad = heappop(attacks)
            attacksum -= ad
        else:
            break
    if h <= attacksum:
        continue
    damage = h - attacksum
    attacksum += damage
    ans += damage
    heappush(attacks, (x + D, damage))

print(ans)
# Original solution
from heapq import heapify, heappush, heappop

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

heap = [(x, h, True) for x, h in XH]
heapify(heap)

ans = 0
bomb_effect = 0
while heap:
    x, h, monster_flg = heappop(heap)
    if monster_flg:
        tairyoku = h - bomb_effect
        if tairyoku > 0:
            new_bomb = -((-tairyoku) // A)
            ans += new_bomb
            heappush(heap, (x + 2 * D + 0.5, new_bomb, False))
            bomb_effect += new_bomb * A
    else:
        bomb_effect -= h * A

print(ans)


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


ans = 0
bomb_effect = 0
bomb_i = 0
bombs = []
for x, h in XH:
    while (bomb_i < len(bombs)) and (x > bombs[bomb_i][0]):
        bomb_effect -= bombs[bomb_i][1] * A
        bomb_i += 1

    tairyoku = h - bomb_effect
    if tairyoku > 0:
        new_bomb = -((-tairyoku) // A)
        ans += new_bomb
        bombs.append((x + 2 * D + 0.5, new_bomb))
        bomb_effect += new_bomb * A

print(ans)
# Original solution
(N,D,A) = list(map(int,input().split()))
l = []
for i in range(N):
    l.append([int(x) for x in input().split()])
    l.sort()
k = [0 for i in range(N)]
for i in range(N):
    k[i] = -((-l[i][1])//A)

m = [0] * N
ub = 0
cnt = 1
for i in range(N):
    if ub < N-1:
        while l[ub + 1][0]-l[i][0] <= 2*D:
            cnt += 1
            ub += 1
            if ub == N - 1:
                break
        m[i] = cnt
    else:
        m[i] = cnt
    cnt -= 1

ans = 0
al = 0
s = [0 for i in range(N)]
j = 0
for i in range(N):
    s[i] = max(k[i]-al,0)
    ans += s[i]
    al += s[i]
    if i < N-1:
        while j+m[j]-1 < i+1:
            al -= s[j]
            if j < N-1:
                j += 1

print(ans)

# Optimized solution
(N,D,A) = list(map(int,input().split()))
l = []
for i in range(N):
    l.append([int(x) for x in input().split()])
l.sort()
k = [0 for i in range(N)]
for i in range(N):
    k[i] = -((-l[i][1])//A)

m = [0] * N
ub = 0
cnt = 1
for i in range(N):
    if ub < N-1:
        while l[ub + 1][0]-l[i][0] <= 2*D:
            cnt += 1
            ub += 1
            if ub == N - 1:
                break
        m[i] = cnt
    else:
        m[i] = cnt
    cnt -= 1

ans = 0
al = 0
s = [0 for i in range(N)]
j = 0
for i in range(N):
    s[i] = max(k[i]-al,0)
    ans += s[i]
    al += s[i]
    if i < N-1:
        while j+m[j]-1 < i+1:
            al -= s[j]
            if j < N-1:
                j += 1

print(ans)
# Original solution
from math import *
import bisect
n, d, a = list(map(int, input().split()))
p = []
for _ in range(n):
  p.append(tuple(map(int, input().split())))

p = sorted(p)
c=0
for i in range(n):
  x, h = p[i]
  if h <= 0: continue
  m = ceil(h/a)
  c+=m
  m = m*a
  for i in range(i+1, n):
    if x + d*2 < p[i][0]:
      break
    p[i] = (p[i][0], p[i][1] - m)
print(c)

# Optimized solution
from math import *

n, d, a = list(map(int, input().split()))
damage_diff = [0] * n
damage = 0
p = sorted(tuple(map(int, input().split())) for _ in range(n))

j = 0
c = 0

for i in range(n):
  damage -= damage_diff[i]
  
  x, h = p[i]
  h -= damage
  if h <= 0: continue
  m = ceil(h/a)
  c += m
  m = m*a
  while j < n and p[j][0] - x <= 2 * d:
    j += 1

  if j < n:
    damage_diff[j] += m
  damage += m
print(c)
# Original solution
from collections import deque

def main():
    N, D, A = list(map(int, input().split()))
    XH = []
    for _ in range(N):
        x, h = list(map(int, input().split()))
        h = (h + A - 1) // A
        XH.append((x, h))
    XH.sort()
    D *= 2
    Q = deque()
    x0, h0 = XH[0]
    Q.append((x0, h0))
    r = h0
    for i, (x, h) in enumerate(XH):
        while Q:
            xx, hh = Q[0]
            if xx < x - D:
                Q.popleft()
            else:
                break
        for xx, hh in Q:
            h -= hh 
            if h <= 0:
                break
        else:
            Q.append((x, h))
            r += h
    print(r)

main()


# Optimized solution
from collections import deque

def main():
    N, D, A = list(map(int, input().split()))
    XH = []
    for _ in range(N):
        x, h = list(map(int, input().split()))
        h = (h + A - 1) // A
        XH.append((x, h))
    XH.sort()
    D *= 2
    Q = deque()
    x0, h0 = XH[0]
    Q.append((x0 + D, h0))
    r = h0
    c = h0
    for x, h in XH:
        while Q and Q[0][0] < x:
            _, hh = Q.popleft()
            c -= hh
        h -= c
        if h > 0:
            Q.append((x + D, h))
            c += h
            r += h
    print(r)

main()
# Original solution
from collections import deque

N, D, A = list(map(int, input().split()))
X = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    X.append((x, h))
X = sorted(X)[::-1]
Q = deque([])

ans = 0
k = 0
while X:
    if len(Q) == 0 or X[-1][0] <= Q[0][0]:
        x, h = X.pop()
        h = max(h - k * A, 0)
        a = (h + A - 1) // A
        ans += a
        k += a
        deque.append(Q, (x + 2 * D, a))
    else:
        x, a = deque.popleft(Q)
        k -= a

print(ans)

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

N, D, A = list(map(int, input().split()))
X = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    X.append((x, h))
X = sorted(X)[::-1]
Q = deque([])

ans = 0
k = 0
while X:
    if len(Q) == 0 or X[-1][0] <= Q[0][0]:
        x, h = X.pop()
        h = max(h - k * A, 0)
        a = (h + A - 1) // A
        ans += a
        k += a
        deque.append(Q, (x + 2 * D, a))
    else:
        x, a = deque.popleft(Q)
        k -= a

print(ans)
# Original solution
import sys
input = sys.stdin.readline
from collections import deque
from operator import itemgetter
key = itemgetter(0)

N, D, A = list(map(int, input().split()))
X = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    X.append((x, h))
X = sorted(X)[::-1]
Q = deque([])

ans = 0
k = 0
while X:
    if len(Q) == 0 or X[-1][0] <= Q[0][0]:
        x, h = X.pop()
        h = max(h - k * A, 0)
        a = (h + A - 1) // A
        ans += a
        k += a
        deque.append(Q, (x + 2 * D, a))
    else:
        x, a = deque.popleft(Q)
        k -= a

print(ans)

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

N, D, A = list(map(int, input().split()))
X = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    X.append((x, h))
X = sorted(X, key = itemgetter(0))[::-1]
Q = deque([])

ans = 0
k = 0
while X:
    if len(Q) == 0 or X[-1][0] <= Q[0][0]:
        x, h = X.pop()
        h = max(h - k * A, 0)
        a = (h + A - 1) // A
        ans += a
        k += a
        deque.append(Q, (x + 2 * D, a))
    else:
        x, a = deque.popleft(Q)
        k -= a

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

N, D, A = list(map(int, input().split()))
X = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    X.append((x, h))
X = sorted(X, key = lambda x: x[0])[::-1]
Q = deque([])

ans = 0
k = 0
while X:
    if len(Q) == 0 or X[-1][0] <= Q[0][0]:
        x, h = X.pop()
        h = max(h - k * A, 0)
        a = (h + A - 1) // A
        ans += a
        k += a
        deque.append(Q, (x + 2 * D, a))
    else:
        x, a = deque.popleft(Q)
        k -= a

print(ans)

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

N, D, A = list(map(int, input().split()))
X = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    X.append((x, h))
X = sorted(X, key = itemgetter(0))[::-1]
Q = deque([])

ans = 0
k = 0
while X:
    if len(Q) == 0 or X[-1][0] <= Q[0][0]:
        x, h = X.pop()
        h = max(h - k * A, 0)
        a = (h + A - 1) // A
        ans += a
        k += a
        deque.append(Q, (x + 2 * D, a))
    else:
        x, a = deque.popleft(Q)
        k -= a

print(ans)
# Original solution
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)


if __name__ == '__main__':
    main()


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


if __name__ == '__main__':
    main()