CodeEff/ECCO huggingface dataset:
# Original solution
import sys
import bisect
from operator import itemgetter

input = sys.stdin.readline


def main():
    N, D, A = [int(x) for x in input().split()]
    XH = []
    X = []
    for _ in range(N):
        x, h = [int(x) for x in input().split()]
        XH.append([x, h, float("inf")])
        XH.append([x + 2 * D + 1, float("inf"), 0])
        X.append(x)
        X.append(x + 2 * D + 1)

    X.sort()
    XH.sort(key=itemgetter(0, 2))

    ans = 0
    ruiseki = 0

    for x, h, r in XH:
        if h != float("inf"):
            if h > ruiseki:
                tmpruiseki = -(-(h - ruiseki) // A) * A
                ans += -(-(h - ruiseki) // A)
                ruiseki += tmpruiseki
                nx = bisect.bisect_left(X, x + 2 * D + 1)
                if XH[nx][1] == float("inf"):
                    XH[nx][2] -= tmpruiseki
                else:
                    XH[nx + 1][2] -= tmpruiseki
            else:
                continue
        else:
            ruiseki += r

    print(ans)


if __name__ == '__main__':
    main()


# Optimized solution
import sys
import bisect
from operator import itemgetter

input = sys.stdin.readline


def main():
    N, D, A = [int(x) for x in input().split()]
    XH = [[None] for _ in range(N * 2)]
    X = [0] * (N * 2)
    for i in range(N):
        x, h = [int(x) for x in input().split()]
        XH[i * 2] = [x, h, float("inf")]
        XH[i * 2 + 1] = [x + 2 * D + 1, float("inf"), 0]
        X[i * 2] = x
        X[i * 2 + 1] = x + 2 * D + 1

    X.sort()
    XH.sort(key=itemgetter(0, 2))

    ans = 0
    ruiseki = 0

    for x, h, r in XH:
        if h != float("inf"):
            if h > ruiseki:
                tmpruiseki = -(-(h - ruiseki) // A) * A
                ans += -(-(h - ruiseki) // A)
                ruiseki += tmpruiseki
                nx = bisect.bisect_left(X, x + 2 * D + 1)
                if XH[nx][1] == float("inf"):
                    XH[nx][2] -= tmpruiseki
                else:
                    XH[nx + 1][2] -= tmpruiseki
            else:
                continue
        else:
            ruiseki += r

    print(ans)


if __name__ == '__main__':
    main()
# Original solution
import sys
import bisect
from operator import itemgetter

input = sys.stdin.readline


def main():
    N, D, A = [int(x) for x in input().split()]
    XH = [[None] for _ in range(N * 2)]
    X = [0] * (N * 2)
    for i in range(N):
        x, h = [int(x) for x in input().split()]
        XH[i * 2] = [x, h, float("inf")]
        XH[i * 2 + 1] = [x + 2 * D + 1, float("inf"), 0]
        X[i * 2] = x
        X[i * 2 + 1] = x + 2 * D + 1

    X.sort()
    XH.sort(key=itemgetter(0, 2))

    ans = 0
    ruiseki = 0

    for x, h, r in XH:
        if h != float("inf"):
            if h > ruiseki:
                tmpruiseki = -(-(h - ruiseki) // A) * A
                ans += -(-(h - ruiseki) // A)
                ruiseki += tmpruiseki
                nx = bisect.bisect_left(X, x + 2 * D + 1)
                if XH[nx][1] == float("inf"):
                    XH[nx][2] -= tmpruiseki
                else:
                    XH[nx + 1][2] -= tmpruiseki
            else:
                continue
        else:
            ruiseki += r

    print(ans)


if __name__ == '__main__':
    main()


# Optimized solution
import sys
import bisect
from operator import itemgetter

input = sys.stdin.readline


def main():
    N, D, A = [int(x) for x in input().split()]
    XH = []
    X = []
    R = [0] * (N * 2)
    for _ in range(N):
        x, h = [int(x) for x in input().split()]
        XH.append((x, h))
        XH.append((x + 2 * D + 1, -float("inf")))
        X.append(x)
        X.append(x + 2 * D + 1)

    X.sort()
    XH.sort(key=itemgetter(0, 1))

    ans = 0
    ruiseki = 0

    for i in range(N * 2):
        x, h = XH[i]
        if h != -float("inf"):
            if h > ruiseki:
                tmpruiseki = -(-(h - ruiseki) // A) * A
                ans += -(-(h - ruiseki) // A)
                ruiseki += tmpruiseki
                nx = bisect.bisect_left(X, x + 2 * D + 1)
                if XH[nx][1] == -float("inf"):
                    R[nx] -= tmpruiseki
                else:
                    R[nx + 1] -= tmpruiseki
            else:
                continue
        else:
            ruiseki += R[i]

    print(ans)


if __name__ == '__main__':
    main()
# Original solution
n,d,a = list(map(int,input().split()))
event = []
for i in range(n):
  x,h = list(map(int,input().split()))
  h = (h-1)//a + 1
  event.append([x,0,i,h])
for i in range(n):
  tmp = event[i][0] + 2 * d
  event.append([tmp,1,i,0])
event.sort()
#print(event)
use = [0 for _ in range(n)]
now = 0
ans = 0
for j in range(2*n):
  x,d,i,h = event[j]
  if d == 0:
    if h <= now:
      pass
    else:
      h -= now
      now += h
      use[i] = h
      ans += h
  else:
    now -= use[i]
  #print(x,d,i,ans,now)
print(ans)

# Optimized solution
n,d,a = list(map(int,input().split()))
raw = []
event = []
for i in range(n):
  x,h = list(map(int,input().split()))
  event.append([x,0,i,h])
for i in range(n):
  tmp = event[i][0] + 2 * d
  event.append([tmp,1,i])
event.sort()
#print(event)
use = [0 for _ in range(n)]
now = 0
ans = 0
for j in range(2*n):
  x,d,i = event[j][:3]
  if d == 0:
    h = event[j][3]
    if h <= now * a:
      pass
    else:
      h -= now * a
      tmp = (h-1)//a+1
      now += tmp
      use[i] = tmp
      ans += tmp
  else:
    now -= use[i]
  #print(x,d,i,ans,now)
print(ans)
# Original solution
n,d,a = list(map(int,input().split()))
raw = []
event = []
for i in range(n):
  x,h = list(map(int,input().split()))
  event.append([x,0,i,h])
for i in range(n):
  tmp = event[i][0] + 2 * d
  event.append([tmp,1,i])
event.sort()
#print(event)
use = [0 for _ in range(n)]
now = 0
ans = 0
for j in range(2*n):
  x,d,i = event[j][:3]
  if d == 0:
    h = event[j][3]
    if h <= now * a:
      pass
    else:
      h -= now * a
      tmp = (h-1)//a+1
      now += tmp
      use[i] = tmp
      ans += tmp
  else:
    now -= use[i]
  #print(x,d,i,ans,now)
print(ans)

# Optimized solution
n,d,a = list(map(int,input().split()))
attack = [0 for _ in range(n)]
event = []
for i in range(n):
  x,h = list(map(int,input().split()))
  h = (h-1)//a+1
  event.append([x-d,0,h,i])
  event.append([x+d,1,h,i])
event.sort()
#print(event)
ans = 0
now = 0
for j in range(2*n):
  x,m,h,i = event[j]
  if m == 0:
    if h > now:
      attack[i] += h-now
      ans += h-now
      now = h
  else:
    now -= attack[i]
print(ans)
# Original solution
f=lambda:list(map(int,input().split()))
n,d,a=f()
lt=sorted([tuple(f()) for _ in range(n)])
from collections import *
q=deque()
c=s=0
for x,h in lt:
  while q and q[0][0]<x: s+=q.popleft()[1]
  h-=s
  if h<1: continue 
  t=-h//a; c-=t; s-=t*a; q.append((x+d*2,t*a))
print(c)

# Optimized solution
import sys
f=lambda:list(map(int,sys.stdin.readline().split()))
n,d,a=f()
lt=sorted(tuple(f()) for _ in range(n))
from collections import *
q=deque()
c=s=0
for x,h in lt:
  while q and q[0][0]<x: s+=q.popleft()[1]
  h-=s
  if h<1: continue 
  t=-h//a; c-=t; s-=t*a; q.append((x+d*2,t*a))
print(c)
# Original solution
#153_F
from bisect import bisect_right
n, d, a = list(map(int, input().split()))
mons = sorted([tuple(map(int, input().split())) for _ in range(n)])
x = [mons[i][0] for i in range(n)]
h = [mons[i][1] for i in range(n)]
cnt = 0
for i in range(n):
    if h[i] <= 0:
        continue
        
    idx = bisect_right(x, x[i] + 2 * d)
    cur_cnt = -(-h[i] // a)
    for j in range(i, idx):
        h[j] -= cur_cnt * a
    
    cnt += cur_cnt
    
print(cnt)

# Optimized solution
#153_F
from bisect import bisect_right
n, d, a = list(map(int, input().split()))
mons = sorted([tuple(map(int, input().split())) for _ in range(n)])
x = [mons[i][0] for i in range(n)]
h = [mons[i][1] for i in range(n)]
damage = [0 for _ in range(n+1)]
cnt = 0
for i in range(n):
    if i > 0:
        damage[i] += damage[i-1]
        if h[i] <= damage[i]:
            continue
    
    cur_cnt = -(-(h[i]-damage[i]) // a)
    cnt += cur_cnt
    damage[i] += cur_cnt * a
    idx = bisect_right(x, x[i] + 2 * d)
    damage[idx] -= cur_cnt * a
    
print(cnt)
# Original solution
import sys,math
sr = sys.stdin.readline
def I(i=0):return [int(x)-i for x in sr().split()]
L1,L2 = [],[]

N,D,A = I()
for i in range(N):
    X,H = I()
    L1.append([X,math.ceil(H/A)])
L1 = sorted(L1)
ans = 0
j = 1
L2 = [-1]*N
for i in range(N):
    lim = L1[i][0] + 2*D
    for k in range(j,N):
        if L1[k][0] > lim:
            L2[i] = k-1
            j = k-1
            break
        elif k == N-1:
            L2[i] = N-1
            j = N-1
for i in range(N):
    x,h = L1[i] 
    if h > 0:
        ans += h
        for j in range(i,L2[i]+1):
            L1[j][1] -= h
print(ans)

# Optimized solution
import sys,math
sr = sys.stdin.readline
def I(i=0):return [int(x)-i for x in sr().split()]
L1,L2 = [],[]

N,D,A = I()
for i in range(N):
    X,H = I()
    L1.append([X,math.ceil(H/A)])
L1 = sorted(L1)
j = 1
L2 = [-1]*N
for i in range(N):
    lim = L1[i][0] + 2*D
    for k in range(j,N):
        if L1[k][0] > lim:
            L2[i] = k-1
            j = k-1
            break
        elif k == N-1:
            L2[i] = N-1
            j = N-1
ans = 0
a,s = 0,0
for i in range(N):
    x,h = L1[i]
    h -= a
    if h > 0:
        ans += h
        a += h
        L1[i][1] = h
    else:
        L1[i][1] = 0
    while s < N and L2[s] <= i:
        a -= L1[s][1]
        s += 1
print(ans)
# Original solution
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]
e.sort()
num = 0

for i in range(n):
    if e[i][1] > 0:
        k = math.ceil(e[i][1]/a)
        num += k
        for j in range(i+1,n):
            if e[j][0] <= e[i][0] + 2*d:
                e[j][1] -= k*a
            else:
                break

print(num)


# Optimized solution
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)
# Original solution
from math import ceil
from bisect import bisect
from operator import itemgetter
class BIT:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)

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

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

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

bit0 = BIT(N)
bit1 = BIT(N)

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

print(ans)

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

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

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

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

c=0
while B:
    x,h=heappop(B)
    sup=x+2*D
    bomb=(h-1)//A+1
    temp=[]
    c+=bomb
    while B:
        X,H=heappop(B)
        if X<=sup:
            H=max(0,H-A*bomb)
            if H>0:
                temp.append((X,H))
        else:
            temp.append((X,H))
            break
    for t in temp:
        heappush(B,t)
print(c)


# Optimized solution
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)
# Original solution
# https://atcoder.jp/contests/abc153/tasks/abc153_f
# 座標圧縮、貪欲法、imos法


import sys
read = sys.stdin.readline


def read_ints():
    return list(map(int, read().split()))


def read_tuple(H):
    '''
    H is number of rows
    '''
    ret = []
    for _ in range(H):
        ret.append(tuple(map(int, read().split())))
    return ret


# まず、何回攻撃すればいいのかを計算する。これがとにかく必要だ(なくてもいいけど)。
#
# 素直な戦略として、左から倒せるギリギリの爆弾を投下して倒すのが最適
# だけどナイーブに実装すると、O(N^2)。だから体力を管理するのが重要。
# どこにどれだけダメージが蓄積したのかはimos法(デルタ関数をおいてから累積和)で管理できる。

from bisect import bisect_left
N, D, A = read_ints()
XH = read_tuple(N)
XH.sort()  # 座標でソート

n_atk = []  # 何回攻撃するのが必要か
X = []  # 座標アクセス用配列
for x, h in XH:
    n_atk.append((h - 1) // A + 1)
    X.append(x)

damege = [0] * (N + 10)  # ダメージ管理用、配列外アクセスがめんどくさいので長めに取る
ans = 0
# j = 0  # 次のxが、今のx+2d以下でもっとも大きなidx
for i, (x, n) in enumerate(zip(X, n_atk)):
    damege[i] += damege[i - 1]  # 積分して、現時点の蓄積回数を表示
    atk = max(0, n - damege[i])  # iには何回攻撃したか
    ans += atk
    # 攻撃下回数を記録
    damege[i] += atk
    # 効果が切れる点を予約 # 尺取ならO(1)で次に行けるけど二分探索でも間に合うか
    damege[bisect_left(X, x + 2 * D + 1, lo=i)] -= atk  # 効果切れを予約

print(ans)


# Optimized solution
# https://atcoder.jp/contests/abc153/tasks/abc153_f
# 座標圧縮、貪欲法、imos法


import sys
read = sys.stdin.readline


def read_ints():
    return list(map(int, read().split()))


def read_tuple(H):
    '''
    H is number of rows
    '''
    ret = []
    for _ in range(H):
        ret.append(tuple(map(int, read().split())))
    return ret


# まず、何回攻撃すればいいのかを計算する。これがとにかく必要だ(なくてもいいけど)。
#
# 素直な戦略として、左から倒せるギリギリの爆弾を投下して倒すのが最適
# だけどナイーブに実装すると、O(N^2)。だから体力を管理するのが重要。
# どこにどれだけダメージが蓄積したのかはimos法(デルタ関数をおいてから累積和)で管理できる。

from bisect import bisect_left
N, D, A = read_ints()
XH = read_tuple(N)
XH.sort()  # 座標でソート

n_atk = []  # 何回攻撃するのが必要か
X = []  # 座標アクセス用配列
for x, h in XH:
    n_atk.append((h - 1) // A + 1)
    X.append(x)

damege = [0] * (N + 10)  # ダメージ管理用、配列外アクセスがめんどくさいので長めに取る
ans = 0
j = 0  # 次のxが、今のx+2d以下でもっとも大きなidx
for i, (x, n) in enumerate(zip(X, n_atk)):
    damege[i] += damege[i - 1]  # 積分して、現時点の蓄積回数を表示
    atk = max(0, n - damege[i])  # iには何回攻撃したか
    ans += atk
    # 攻撃下回数を記録
    damege[i] += atk
    # 効果が切れる点を予約 # 尺取ならO(1)で次に行けるけど二分探索でも間に合うか
    while j < len(X) and X[j] < x + 2 * D + 1:
        j += 1
    damege[j] -= atk  # 効果切れを予約

print(ans)
# Original solution
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.sort()
ans = 0
for i in range(N):
    h = int(X[i][1])
    if h != 0:
        x = int(X[i][0])
        if h % A == 0:
            count = h // A
        else:
            count = h // A + 1
        ans += count
        dmg = A * count
    #print(ans,dmg)
        for j in range(i+1,N):
            x2 = int(X[j][0])
            h2 = int(X[j][1])
            if  x + (2 * D) < x2:
                break
            else:
                X[j][1] = max(0,h2-dmg)
                #print(X[j])
print(ans)

# Optimized solution
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.sort()
if X[-1][0] - X[0][0] < 2 * D:
    ans = 0 
    max = 0
    for i in range(N):
        if X[i][1] > max:
            max = X[i][1]
    if max % A == 0:
        ans = max // A
    else:
        ans = max // A + 1
else:
    ans = 0
    for i in range(N):
        h = int(X[i][1])
        if h != 0:
            x = int(X[i][0])
            if h % A == 0:
                count = h // A
            else:
                count = h // A + 1
            ans += count
            dmg = A * count
    #print(ans,dmg)
            for j in range(i+1,N):
                x2 = int(X[j][0])
                h2 = int(X[j][1])
                if  x + (2 * D) < x2:
                    break
                else:
                    X[j][1] = max(0,h2-dmg)
                    #print(X[j])
print(ans)
# Original solution
import sys
input = sys.stdin.buffer.readline

def main():
    n, d, a = list(map(int, input().split()))
    XH = []
    for i in range(n):
        x, h = list(map(int, input().split()))
        XH.append((x, h))

    XH.sort()
    from collections import deque
    q = deque()

    ans = 0
    import copy
    for x, h in XH:
        nq = deque()
        while q:
            r, s = q.popleft()
            if r+d < x:
                continue
            else:
                h -= s
                nq.append((r, s))
        #print(x, h)
        if h > 0:
            if h%a == 0:
                b = h//a
                ans += b
                nq.append((x+d, a*b))
            else:
                b = h//a+1
                ans += b
                nq.append((x+d, a*b))
        q = copy.copy(nq)
        #print(q)
        #print(ans)
    print(ans)

if __name__ == '__main__':
    main()


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

def main():
    n, d, a = list(map(int, input().split()))
    XH = []
    for i in range(n):
        x, h = list(map(int, input().split()))
        XH.append((x, h))

    XH.sort()
    from collections import deque
    q = deque()

    ans = 0
    t = 0
    import copy
    for x, h in XH:
        while q:
            r, s = q.popleft()
            if r+d < x:
                t -= s
            else:
                q.appendleft((r, s))
                break
        h -= t
        if h > 0:
            if h%a == 0:
                b = h//a
                ans += b
                t += a*b
                q.append((x+d, a*b))
            else:
                b = h//a+1
                ans += b
                t += a*b
                q.append((x+d, a*b))
    print(ans)

if __name__ == '__main__':
    main()
# Original solution
import sys
input = sys.stdin.buffer.readline

def main():
    n, d, a = list(map(int, input().split()))
    XH = []
    for i in range(n):
        x, h = list(map(int, input().split()))
        XH.append((x, h))

    XH.sort()
    from collections import deque
    q = deque()

    ans = 0
    t = 0
    import copy
    for x, h in XH:
        while q:
            r, s = q.popleft()
            if r+d < x:
                t -= s
            else:
                q.appendleft((r, s))
                break
        h -= t
        if h > 0:
            if h%a == 0:
                b = h//a
                ans += b
                t += a*b
                q.append((x+d, a*b))
            else:
                b = h//a+1
                ans += b
                t += a*b
                q.append((x+d, a*b))
    print(ans)

if __name__ == '__main__':
    main()


# Optimized solution
class BIT:
    def __init__(self, n):
        self.n = n
        self.bit = [0]*(self.n+1) # 1-indexed

    def init(self, init_val):
        for i, v in enumerate(init_val):
            self.add(i, v)

    def add(self, i, x):
        # i: 0-indexed
        i += 1 # to 1-indexed
        while i <= self.n:
            self.bit[i] += x
            i += (i & -i)

    def sum(self, i, j):
        # return sum of [i, j)
        # i, j: 0-indexed
        return self._sum(j) - self._sum(i)

    def _sum(self, i):
        # return sum of [0, i)
        # i: 0-indexed
        res = 0
        while i > 0:
            res += self.bit[i]
            i -= i & (-i)
        return res

class RangeAddBIT:
    def __init__(self, n):
        self.n = n
        self.bit1 = BIT(n)
        self.bit2 = BIT(n)

    def init(self, init_val):
        self.bit2.init(init_val)

    def add(self, l, r, x):
        # add x to [l, r)
        # l, r: 0-indexed
        self.bit1.add(l, x)
        self.bit1.add(r, -x)
        self.bit2.add(l, -x*l)
        self.bit2.add(r, x*r)

    def sum(self, l, r):
        # return sum of [l, r)
        # l, r: 0-indexed
        return self._sum(r) - self._sum(l)

    def _sum(self, i):
        # return sum of [0, i)
        # i: 0-indexed
        return self.bit1._sum(i)*i + self.bit2._sum(i)

import sys
import io, os
#input = sys.stdin.buffer.readline
input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline

n, d, a = list(map(int, input().split()))
XH = []
for i in range(n):
    x, h = list(map(int, input().split()))
    XH.append((x-d, h))
XH.sort()
X = []
H = []
for x, h in XH:
    X.append(x)
    H.append(h)

bit = RangeAddBIT(n+1)
bit.init(H)
import bisect
ans = 0
for i in range(n):
    h = bit.sum(i, i+1)
    if h > 0:
        q = (h+a-1)//a
        ans += q
        j = bisect.bisect_right(X, X[i]+2*d)
        bit.add(i, j, -q*a)
print(ans)
# Original solution
#!/usr/bin/env python3

import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

def bit_add(i,w):
    x = i+1
    while x <= n:
        bit[x-1] += w
        x += x & -x
    return

def bit_sum(i):
    res = 0
    x = i+1
    while x > 0:
        res += bit[x-1]
        x -= x & -x
    return res

n,d,a = LI()
bit = [0]*(n+1)
xh = [LI() for _ in range(n)]
xh.sort()
X = [x for x,_ in xh]
lst = []
for x,h in xh:
    r = br(X,x+2*d)
    lst.append((x,h,r))

ans = 0
for i in range(n):
    x,h,r = lst[i]
    tmp = max(0,math.ceil((h - bit_sum(i))/a))
    ans += tmp
    bit_add(r,-tmp*a)
    bit_add(i,tmp*a)
print(ans)


# Optimized solution
#!/usr/bin/env python3

import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

#BinaryIndexedTree
def bit_add(i,w):
    x = i+1
    while x <= n:
        bit[x-1] += w
        x += x & -x
    return

def bit_sum(i):
    res = 0
    x = i+1
    while x > 0:
        res += bit[x-1]
        x -= x & -x
    return res

n,d,a = LI()
bit = [0]*(n+1)
xh = [LI() for _ in range(n)]
xh.sort()
X = [x for x,_ in xh]
lst = []
for i in range(n):
    x,h = xh[i]
    r = br(X,x+2*d)
    lst.append((i,h,r))

ans = 0
for i,h,r in lst:
    tmp = max(0,math.ceil((h - bit_sum(i))/a))
    ans += tmp
    bit_add(r,-tmp*a)
    bit_add(i,tmp*a)
print(ans)