"""



普通に端っこを基準にして、貪欲的に爆弾をおいていく方法を考えるのがよさそう。

座標圧縮したうえで、遅延セグ木で各座標に蓄積しているダメージを管理しておけばよい。

一番左端のやつの体力を削れるだけの爆弾を設置してみる:O(1)

次の左端になるモンスターの位置(体力が1以上あるモンスターのなかで一番左端のやつの座標)を探す。これはO(logN)かかる。

このサイクルをモンスターが全滅するまで行うので、O(N)サイクル回す。したがって全体でO(NlogN)

"""

from math import ceil

class lazySegTree:

    def __init__(self,n):

        self.end_leave = 2**(n.bit_length()+1)

        self.tree = [0]*(2*self.end_leave)

        self.lazy = [0]*(2*self.end_leave)



    def gindex(self,left,right):

        #leftとrightの真上にあるノードを返す

        left = left + self.end_leave

        right = right + self.end_leave

        left >>= 1

        while left:

            yield left

            left >>= 1



        right >>= 1

        while right:

            yield right

            right >>= 1



    def add(self,left,right,x):

        L = left + self.end_leave

        R = right + self.end_leave

        while L < R:

            if L&1:

                self.lazy[L] += x

                self.tree[L] += x

                L += 1

            if R&1:

                R -= 1

                self.lazy[R] += x

                self.tree[R] += x

            L >>= 1

            R >>= 1

        for i in self.gindex(left,right):

            self.tree[i] = max(self.tree[i*2],self.tree[i*2+1])+self.lazy[i]

    

    def propagates(self,*ids):

        for i in reversed(ids):

            self.lazy[i*2] += self.lazy[i]

            self.lazy[i*2+1] += self.lazy[i]

            self.tree[i*2] += self.lazy[i]

            self.tree[i*2+1] += self.lazy[i]

            self.lazy[i] = 0



    def get(self,left,right):

        self.propagates(*self.gindex(left,right))

        L = left + self.end_leave

        R = right + self.end_leave

        res = 0

        while L < R:

            if L&1:

                res = max(res,self.tree[L])

                L += 1

            if R&1:

                R -= 1

                res = max(res,self.tree[R])

            L >>= 1

            R >>= 1

        return res

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

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

XH.sort()

compSet = []

for x,h in XH:

    compSet.append(x)

    compSet.append(x+2*D)

compSet.sort()

compSet = sorted(set(compSet))

compDic = {x:i for i,x in enumerate(compSet)}



LST = lazySegTree(len(compDic))

ans = 0

for x,h in XH:

    compX = compDic[x]

    h -= LST.get(compX,compX+1)

    if h > 0:

        bomb = ceil(h/A)

        ans += bomb

        damage = bomb*A

        compRight = compDic[x+2*D]

        LST.add(compX,compRight+1,damage)

print(ans)



"""

lazyseg使う方法とかもあるが、imos法使うのが簡単そう。

座標圧縮は必須。

"""

from math import ceil

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

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

XH.sort()



coordinates = set()

for x,h in XH:

    coordinates.add(x)

    coordinates.add(x+2*D+1)



compress = {x:i for i,x in enumerate(sorted(coordinates))}



imos = [0]*(len(compress))

damage = 0

cur = 0

ans = 0

for x,h in XH:

    compX = compress[x]

    while cur <= compX:

        damage += imos[cur]

        cur += 1

    rest = h-damage

    if rest > 0:

        add = A*ceil(rest/A)

        ans += int(ceil(rest/A))

        imos[cur] += add

        right = compress[x+2*D+1]

        imos[right] -= add

print(ans)
"""
普通に端っこを基準にして、貪欲的に爆弾をおいていく方法を考えるのがよさそう。
座標圧縮したうえで、遅延セグ木で各座標に蓄積しているダメージを管理しておけばよい。
一番左端のやつの体力を削れるだけの爆弾を設置してみる:O(1)
次の左端になるモンスターの位置(体力が1以上あるモンスターのなかで一番左端のやつの座標)を探す。これはO(logN)かかる。
このサイクルをモンスターが全滅するまで行うので、O(N)サイクル回す。したがって全体でO(NlogN)
"""
from math import ceil


class lazySegTree:
    def __init__(self, n):
        self.end_leave = 2 ** (n.bit_length() + 1)
        self.tree = [0] * (2 * self.end_leave)
        self.lazy = [0] * (2 * self.end_leave)

    def gindex(self, left, right):
        # leftとrightの真上にあるノードを返す
        left = left + self.end_leave
        right = right + self.end_leave
        left >>= 1
        while left:
            yield left
            left >>= 1
        right >>= 1
        while right:
            yield right
            right >>= 1

    def add(self, left, right, x):
        L = left + self.end_leave
        R = right + self.end_leave
        while L < R:
            if L & 1:
                self.lazy[L] += x
                self.tree[L] += x
                L += 1
            if R & 1:
                R -= 1
                self.lazy[R] += x
                self.tree[R] += x
            L >>= 1
            R >>= 1
        for i in self.gindex(left, right):
            self.tree[i] = max(self.tree[i * 2], self.tree[i * 2 + 1]) + self.lazy[i]

    def propagates(self, *ids):
        for i in reversed(ids):
            self.lazy[i * 2] += self.lazy[i]
            self.lazy[i * 2 + 1] += self.lazy[i]
            self.tree[i * 2] += self.lazy[i]
            self.tree[i * 2 + 1] += self.lazy[i]
            self.lazy[i] = 0

    def get(self, left, right):
        self.propagates(*self.gindex(left, right))
        L = left + self.end_leave
        R = right + self.end_leave
        res = 0
        while L < R:
            if L & 1:
                res = max(res, self.tree[L])
                L += 1
            if R & 1:
                R -= 1
                res = max(res, self.tree[R])
            L >>= 1
            R >>= 1
        return res


N, D, A = list(map(int, input().split()))
XH = [list(map(int, input().split())) for _ in range(N)]
XH.sort()
compSet = []
for x, h in XH:
    compSet.append(x)
    compSet.append(x + 2 * D)
compSet.sort()
compSet = sorted(set(compSet))
compDic = {x: i for i, x in enumerate(compSet)}
LST = lazySegTree(len(compDic))
ans = 0
for x, h in XH:
    compX = compDic[x]
    h -= LST.get(compX, compX + 1)
    if h > 0:
        bomb = ceil(h / A)
        ans += bomb
        damage = bomb * A
        compRight = compDic[x + 2 * D]
        LST.add(compX, compRight + 1, damage)
print(ans)

"""
lazyseg使う方法とかもあるが、imos法使うのが簡単そう。
座標圧縮は必須。
"""
from math import ceil

N, D, A = list(map(int, input().split()))
XH = [list(map(int, input().split())) for _ in range(N)]
XH.sort()
coordinates = set()
for x, h in XH:
    coordinates.add(x)
    coordinates.add(x + 2 * D + 1)
compress = {x: i for i, x in enumerate(sorted(coordinates))}
imos = [0] * (len(compress))
damage = 0
cur = 0
ans = 0
for x, h in XH:
    compX = compress[x]
    while cur <= compX:
        damage += imos[cur]
        cur += 1
    rest = h - damage
    if rest > 0:
        add = A * ceil(rest / A)
        ans += int(ceil(rest / A))
        imos[cur] += add
        right = compress[x + 2 * D + 1]
        imos[right] -= add
print(ans)

-普通に端っこを基準にして、貪欲的に爆弾をおいていく方法を考えるのがよさそう。 -座標圧縮したうえで、遅延セグ木で各座標に蓄積しているダメージを管理しておけばよい。 -一番左端のやつの体力を削れるだけの爆弾を設置してみる:O(1) -次の左端になるモンスターの位置(体力が1以上あるモンスターのなかで一番左端のやつの座標)を探す。これはO(logN)かかる。 -このサイクルをモンスターが全滅するまで行うので、O(N)サイクル回す。したがって全体でO(NlogN) +lazyseg使う方法とかもあるが、imos法使うのが簡単そう。 +座標圧縮は必須。 - - -class lazySegTree: -    def __init__(self, n): -        self.end_leave = 2 ** (n.bit_length() + 1) -        self.tree = [0] * (2 * self.end_leave) -        self.lazy = [0] * (2 * self.end_leave) - -    def gindex(self, left, right): -        # leftとrightの真上にあるノードを返す -        left = left + self.end_leave -        right = right + self.end_leave -        left >>= 1 -        while left: -            yield left -            left >>= 1 -        right >>= 1 -        while right: -            yield right -            right >>= 1 - -    def add(self, left, right, x): -        L = left + self.end_leave -        R = right + self.end_leave -        while L < R: -            if L & 1: -                self.lazy[L] += x -                self.tree[L] += x -                L += 1 -            if R & 1: -                R -= 1 -                self.lazy[R] += x -                self.tree[R] += x -            L >>= 1 -            R >>= 1 -        for i in self.gindex(left, right): -            self.tree[i] = max(self.tree[i * 2], self.tree[i * 2 + 1]) + self.lazy[i] - -    def propagates(self, *ids): -        for i in reversed(ids): -            self.lazy[i * 2] += self.lazy[i] -            self.lazy[i * 2 + 1] += self.lazy[i] -            self.tree[i * 2] += self.lazy[i] -            self.tree[i * 2 + 1] += self.lazy[i] -            self.lazy[i] = 0 - -    def get(self, left, right): -        self.propagates(*self.gindex(left, right)) -        L = left + self.end_leave -        R = right + self.end_leave -        res = 0 -        while L < R: -            if L & 1: -                res = max(res, self.tree[L]) -                L += 1 -            if R & 1: -                R -= 1 -                res = max(res, self.tree[R]) -            L >>= 1 -            R >>= 1 -        return res - -compSet = [] +coordinates = set() -    compSet.append(x) -    compSet.append(x + 2 * D) -compSet.sort() -compSet = sorted(set(compSet)) -compDic = {x: i for i, x in enumerate(compSet)} -LST = lazySegTree(len(compDic)) +    coordinates.add(x) +    coordinates.add(x + 2 * D + 1) +compress = {x: i for i, x in enumerate(sorted(coordinates))} +imos = [0] * (len(compress)) +damage = 0 +cur = 0 -    compX = compDic[x] -    h -= LST.get(compX, compX + 1) -    if h > 0: -        bomb = ceil(h / A) -        ans += bomb -        damage = bomb * A -        compRight = compDic[x + 2 * D] -        LST.add(compX, compRight + 1, damage) +    compX = compress[x] +    while cur <= compX: +        damage += imos[cur] +        cur += 1 +    rest = h - damage +    if rest > 0: +        add = A * ceil(rest / A) +        ans += int(ceil(rest / A)) +        imos[cur] += add +        right = compress[x + 2 * D + 1] +        imos[right] -= add