Problem:
 Score : 600 points    Problem Statement Silver Fox is fighting with N monsters.  The monsters are standing in a row, and we can assume them to be standing on a number line. The i -th monster, standing at the coordinate X_i , has the health of H_i .  Silver Fox can use bombs to attack the monsters.
Using a bomb at the coordinate x decreases the healths of all monsters between the coordinates x-D and x+D (inclusive) by A .
There is no way other than bombs to decrease the monster's health.  Silver Fox wins when all the monsters' healths become 0 or below.  Find the minimum number of bombs needed to win.      Constraints  1 \leq N \leq 2 \times 10^5  0 \leq D \leq 10^9  1 \leq A \leq 10^9  0 \leq X_i \leq 10^9  1 \leq H_i \leq 10^9  X_i are distinct.  All values in input are integers.         Input Input is given from Standard Input in the following format:  N  D  A  X_1  H_1  :  X_N  H_N       Output Print the minimum number of bombs needed to win.        Sample Input 1 3 3 2
1 2
5 4
9 2      Sample Output 1 2  First, let us use a bomb at the coordinate 4 to decrease the first and second monsters' health by 2 .  Then, use a bomb at the coordinate 6 to decrease the second and third monsters' health by 2 .  Now, all the monsters' healths are 0 .
We cannot make all the monsters' health drop to 0 or below with just one bomb.       Sample Input 2 9 4 1
1 5
2 4
3 3
4 2
5 1
6 2
7 3
8 4
9 5      Sample Output 2 5  We should use five bombs at the coordinate 5 .       Sample Input 3 3 0 1
300000000 1000000000
100000000 1000000000
200000000 1000000000      Sample Output 3 3000000000  Watch out for overflow.

Solution (Python):
import math
n, d, a = map(int,input().split())
e = [[] for i in range(n)]
for i in range(n):
    x, h = 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)

Solution (Python):
def main():
    import sys
    input = sys.stdin.readline
    sys.setrecursionlimit(10**7)
    from collections import Counter, deque
    
    from itertools import combinations, permutations, accumulate, groupby, product
    from bisect import bisect_left,bisect_right
    from heapq import heapify, heappop, heappush
    from math import floor, ceil
    

    
    

    n,d,a = map(int, input().split())
    xh = [list(map(int, input().split())) for _ in range(n)]
    xh.sort(key=lambda a: a[0])
    x = []
    for i in range(n):
        x.append(xh[i][0])
    res = 0
    hp = [0]*n
    for i in range(n):
        if i != 0:
            hp[i] += hp[i-1]
        if hp[i]>=xh[i][1]:
            continue
        res += (xh[i][1]-hp[i]-1) // a + 1
        attack = ((xh[i][1]-hp[i]-1) // a + 1) * a
        hp[i] += attack
        genkai = x[i] + 2 * d
        migi = bisect_right(x, genkai)
        if migi <= n - 1:
            hp[migi] -= attack

    print(res)

if __name__ == '__main__':
    main()

Solution (Python):
def main():
    import sys
    input = sys.stdin.readline
    sys.setrecursionlimit(10**7)
    from collections import Counter, deque
    
    from itertools import combinations, permutations, accumulate, groupby, product
    from bisect import bisect_left,bisect_right
    from heapq import heapify, heappop, heappush
    from math import floor, ceil
    

    
    

    n,d,a = map(int, input().split())
    xh = [list(map(int, input().split())) for _ in range(n)]
    xh.sort(key=lambda a: a[0])
    x = []
    for i in range(n):
        x.append(xh[i][0])
    res = 0
    hp = [0]*n
    for i in range(n):
        if i != 0:
            hp[i] += hp[i-1]
        if hp[i]>=xh[i][1]:
            continue
        res += (xh[i][1]-hp[i]-1) // a + 1
        attack = ((xh[i][1]-hp[i]-1) // a + 1) * a
        hp[i] += attack
        genkai = x[i] + 2 * d
        migi = bisect_right(x, genkai)
        if migi <= n - 1:
            hp[migi] -= attack

    print(res)

if __name__ == '__main__':
    main()

Solution (Python):
from math import ceil
from collections import deque
n,d,a = map(int, input().split())

monster = [list(map(int,input().split())) for i in range(n)]

monster.sort()

damage = 0

finish = deque()

ans = 0

for i in range(n):
    x,h = monster[i]
    while finish:
        if finish[0][0]<x:
            damage -= finish.popleft()[1]
        else:
            break
    if h<=damage:
        continue
    else:
        b = ceil((h-damage)/a)
        ans += b
        damage += b*a
        finish.append([x+2*d,b*a])

print(ans)

Solution (Python):
from bisect import bisect_left
def main():
    n, dis, dam = map(int, input().split())
    mon = [list(map(int, input().split())) for _ in range(n)]
    mon.sort(key=lambda x: x[0])
    p = [v[0] for v in mon]
    imos = [0]*(n+1)
    dis = 2*dis + 1
    ans = 0
    for i in range(n):
        if 0 < i:
            imos[i] += imos[i-1]
        if imos[i] < mon[i][1]:
            tmp = (mon[i][1] - imos[i] + dam - 1) // dam
            ans += tmp
            tmp *= dam
            imos[i] += tmp
            idx = bisect_left(p, p[i]+dis)
            imos[idx] -= tmp
    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):
f=lambda: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>0: t=-h//a; c-=t; s-=t*a; q.append((x+d*2,t*a))
print(c)

Solution (Python):
f=lambda: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>0: t=-h//a; c-=t; s-=t*a; q.append((x+d*2,t*a))
print(c)

Solution (Python):
f=lambda: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)

Solution (Python):
import sys
f=lambda: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)

Solution (Python):
import sys
f=lambda: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)

Solution (Python):
f=lambda: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)

Solution (Python):
f=lambda: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)

Solution (Python):

import sys
from bisect import bisect_left,bisect_right
sys.setrecursionlimit(10**9)
INF=10**18
MOD=10**9+7
input=lambda: sys.stdin.readline().rstrip()
YesNo=lambda b: bool([print('Yes')] if b else print('No'))
YESNO=lambda b: bool([print('YES')] if b else print('NO'))
int1=lambda x:int(x)-1

def main():
    class RangeBIT:
        def __init__(self,n):
            self.p=self.BIT(n+1)
            self.q=self.BIT(n+1)
        
        def add(self,s,t,x):
            self.p.add(s,-x*s)
            self.p.add(t,x*t)
            self.q.add(s,x)
            self.q.add(t,-x)
        
        def sum(self,s,t):
            return self.p.sum(t)+self.q.sum(t)*t-self.p.sum(s)-self.q.sum(s)*s
        
        class BIT:
            def __init__(self,n):
                self.num=n
                self.dat=[0]*(self.num+1)
            
            def add(self,i,x):
                i+=1
                while i<=self.num:
                    self.dat[i]+=x
                    i+=i&-i
            
            def sum(self,i):
                i+=1
                s=0
                while i>0:
                    s+=self.dat[i]
                    i-=i&-i
                return s

    N,D,A=map(int,input().split())
    X=[0]*N
    XH=[]
    for i in range(N):
        X[i],H=map(int,input().split())
        XH.append((X[i]-1,H))
    XH.sort()
    X.sort()
    l=[0]*N
    for i in range(N):
        l[i]=bisect_right(X,X[i]+D*2)-i
    
    b=RangeBIT(N)
    index=0
    ans=0
    while index<N:
        h=XH[index][1]-b.sum(index,index+1)
        if h<=0:
            index+=1
            continue
        d=-(-h//A)
        ans+=d
        b.add(index,index+l[index],d*A)
    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
import heapq

N, D, A = map(int, input().split(" "))
proc_que = []

for _ in range(N):
    x, h = map(int, input().split(" "))
    heapq.heappush(proc_que, (x, h))

damaged = 0
ans = 0

while len(proc_que) > 0:
    x, h = heapq.heappop(proc_que)
    if h > 0:
        
        num_bomb_use = max(0, (h - damaged + A - 1) // A)
        ans += num_bomb_use
        damaged += num_bomb_use * A
        heapq.heappush(proc_que, (x + 2 * D + 1, -num_bomb_use * A))
    else:
        
        damaged += h

print(ans)

Solution (Python):
n, d, a = map(int, input().split())
XH = [tuple(map(int, input().split())) for i in range(n)]
XH.sort()
X = [x for x, h in XH]
H = [h for x, h in XH]
X.append(10**10)
H.append(0)
j = 0
S = [0]*(n+1)
ans = 0
for i in range(n):
    H[i] = max(0, H[i]-S[i])
    c = -(-H[i]//a)
    while X[j] <= X[i] + 2*d:
        j += 1
    S[i+1] += S[i] + a*c
    S[j] -= a*c
    ans += c
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline

import bisect


n,d,a = 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)

Solution (Python):


import sys
import math













from bisect import bisect_left, bisect_right 




def main():
    mod = 1000000007                  
    inf = float('inf')
    sys.setrecursionlimit(10**6)    
    def input(): return sys.stdin.readline().rstrip()
    def ii():  return int(input())
    def mi():  return map(int, input().split())
    def mi_0(): return map(lambda x: int(x)-1, input().split())
    def lmi(): return list(map(int, input().split()))
    def lmi_0(): return list(map(lambda x: int(x)-1, input().split()))
    def li():  return list(input())
    
    
    n, d, a = mi()
    monsters = sorted([lmi() for _ in range(n)])
    monster_points = []
    monster_hps= []
    for pair in monsters:
        monster_points.append(pair[0])
        monster_hps.append(pair[1])
    
    
    right_end_monster_ind = [0] * (n)
    for i in range(n):
        right_end_monster_ind[i] = bisect_right(monster_points, monster_points[i]+2*d) - 1
    
    
    imos_list = [0] * (n+1)
    damage = 0
    ans = 0
    for i in range(n):
        damage += imos_list[i]
        rest_hp = max(0, monster_hps[i] - damage)
        
        cnt = math.ceil(rest_hp / a)
        ans += cnt
        imos_list[i+1] += (a * cnt)
        imos_list[right_end_monster_ind[i]+1] -= (a * cnt)
        
    
    print(ans)    


if __name__ == "__main__":
    main()

Solution (Python):
def main():  
  import sys
  input = sys.stdin.readline
  n, d, a = [int(i) for i in input().split()]
  chk = []
  for i in range(n):
    x, h = [int(i) for i in input().split()]
    chk.append((x, 0, h))

  from heapq import heapify, heappop, heappush
  heapify(chk)
  atk_cnt = 0; ans = 0
  while chk:
    x, t, h = heappop(chk)
    if t == 0:
      if atk_cnt * a >= h:
          continue
      remain = h - atk_cnt * a
      new_atk = (remain - 1) // a + 1
      heappush(chk, (x + 2 * d, 1, new_atk))
      ans += new_atk
      atk_cnt += new_atk
    else:
      atk_cnt -= h
  print(ans)
if __name__ == '__main__':
    main()

Solution (Python):
from collections import Counter,defaultdict,deque
from heapq import heappop,heappush,heapify
from bisect import bisect_left 
import sys,math,itertools,fractions,pprint
sys.setrecursionlimit(10**8)
mod = 10**9+7
INF = float('inf')
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))

n,d,A = inpl()
d *= 2
xh = [inpl() for _ in range(n)]
xh.sort()
ln = 1
f = [0]
a = [0]
for i in range(n):
    x,h = xh[i]
    r = bisect_left(f,x+d)
    l = bisect_left(f,x)
    tmp = a[r-1] - a[l-1]
    
    h -= tmp * A
    if h > 0:
        ind = x + d
        att = (h+A-1)//A
        f.append(ind)
        a.append(a[-1] + att)
        ln += 1

print(a[-1])

Solution (Python):
def main():
    from collections import deque, namedtuple
    from operator import attrgetter
    import sys
    input = sys.stdin.readline

    Mon = namedtuple('Mon', 'x h')  
    Eff = namedtuple('Eff', 'x cnt')  

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

    ms = []
    for _ in range(N):
        x, h = map(int, input().split())
        m = Mon(x=x, h=h)
        ms.append(m)

    ms.sort(key=attrgetter('x'))

    dq = deque()

    effect = 0
    cnt = 0
    for m in ms:
        while dq and dq[0].x < m.x:
            e = dq.popleft()
            effect -= e.cnt * A
        need_dmg = max(0, m.h - effect)
        if need_dmg:
            need_cnt = (need_dmg + A - 1) // A
            e = Eff(x=m.x + D * 2, cnt=need_cnt)
            dq.append(e)
            effect += need_cnt * A
            cnt += need_cnt
    print(cnt)


if __name__ == '__main__':
    main()

Solution (Python):
def main():
    from collections import deque, namedtuple
    from operator import attrgetter
    import sys
    input = sys.stdin.readline

    Mon = namedtuple('Mon', 'x h')  
    Eff = namedtuple('Eff', 'x cnt')  

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

    ms = []
    for _ in range(N):
        x, h = map(int, input().split())
        m = Mon(x=x, h=h)
        ms.append(m)

    ms.sort(key=attrgetter('x'))

    dq = deque()

    effect = 0
    cnt = 0
    for m in ms:
        while dq and dq[0].x < m.x:
            e = dq.popleft()
            effect -= e.cnt * A
        need_dmg = max(0, m.h - effect)
        if need_dmg:
            need_cnt = (need_dmg + A - 1) // A
            e = Eff(x=m.x + D * 2, cnt=need_cnt)
            dq.append(e)
            effect += need_cnt * A
            cnt += need_cnt
    print(cnt)


if __name__ == '__main__':
    main()

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



X.append(10**10)
H.append(0)
j = 0
c = 0
S = [0]*(n+1)
for i in range(n):
    H[i] = max(0, H[i]-S[i])
    c += -(-H[i]//a)
    while X[j] <= X[i] + 2*d:
        j += 1
    S[i+1] += S[i] + -(-H[i]//a)*a
    S[j] -= -(-H[i]//a)*a
    
    
    


print(c)

Solution (Python):
import math
N,D,A = map(int,input().split())
l = []
for i in range(N):
  l.append(list(map(int,input().split())))
l.sort()  
lx = []
lc = []
for i in l:
  X,H = i[0],i[1]
  lx.append(X)
  lc.append(math.ceil(H/A))

migi = []
m = 0
i = 0
while i <= N-1:
  if lx[m] - lx[i] > 2*D:
    migi.append(m)
    i += 1
  elif m != N-1:
    m += 1
  elif m == N-1:
    migi.append(-1)
    i += 1 

cnt = 0
dam = [0 for i in range(N)]
for i in range(N):
  if dam[i] < lc[i]:
    c = lc[i] - dam[i]  
    dam[i] += c
    if migi[i] >= 0:
      dam[migi[i]] -= c
    cnt += c
  if i <=N-2:
    dam[i+1] += dam[i]   
print(cnt)

Solution (Python):
N,d,a = map(int,input().split())



data0 = [0]*(N+1)
data1 = [0]*(N+1)

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)

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

xhl = sorted(xhl)
xl = [x for x,h in xhl]

for idx in range(N):
    add(idx+1, idx+2, xhl[idx][1])

def ceil(a, b):
   return a // b + (a % b > 0)

import bisect

ans = 0
for i in range(N):
    hp = query(i + 1, i + 2)
    if hp > 0:
        count = ceil(hp, a)
        ans += count
        damage = count * a
        idx = bisect.bisect_right(xl, xl[i] + 2*d)
        add(i+1, idx+1, -damage)
print(ans)

Solution (Python):

n,d,a=map(int,input().split())
xh=[]
for i in range(n):
  xx,hh=map(int,input().split())
  xh.append([xx,hh])
xh.sort(key=lambda x:x[0])
xl=[x for x,h in xh]

from math import ceil
from bisect import bisect_right

ans=0
damage=[0]*(n+1)

for i in range(n):
  x,h=xh[i]
  if damage[i]<h:
    need=ceil((h-damage[i])/a)
    right=x+2*d
    
    r_idx=bisect_right(xl,right)
    
    damage[i]+=need*a
    damage[r_idx]-=need*a
    ans+=need
  
  damage[i+1]+=damage[i]
print(ans)

Solution (Python):
import math
from collections import deque
N,D,A = map(int,input().split(' '))
XHn = [ list(map(int,input().split(' '))) for _ in range(N)]
ans = 0
XHn.sort()
attacks = deque([]) 
attack = 0
ans = 0
for i  in range(N):
    x = XHn[i][0]
    h = XHn[i][1]
    while len(attacks) > 0 and x > attacks[0][0]:
        distance,attack_num = attacks.popleft()
        attack -= attack_num*A
    if h > attack:
        diff = h - attack 
        distance_attack = x + D*2
        need_attack = math.ceil(diff/A)
        attacks.append((distance_attack,need_attack))
        attack += A*need_attack
        ans += need_attack
print(ans)

Solution (Python):
import bisect
import sys
input = sys.stdin.readline

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

x.sort()
y=[]
for i in range(n):
    y.append(x[i][0])
    x[i][1]=-(-x[i][1]//a)


ans=0

z=[0]*(n+1)

atk=0
for i in range(n):
    atk+=z[i]
    if x[i][1]-atk>0:
        ans+=x[i][1]-atk
        q=bisect.bisect_right(y,x[i][0]+2*d,i,n)
        z[q]-=x[i][1]-atk
        atk+=x[i][1]-atk
print(ans)

Solution (Python):
import bisect
import math
N,D,A=map(int,input().split())
tmp=[list(map(int,input().split())) for i in range(N)]
tmp.sort(key=lambda x:x[0])
monster=[];X=[]
for i in range(N):
    monster.append(tmp[i][1]);X.append(tmp[i][0])
minus=[0]*(N+1)
ans=0
damage=0
for i in range(N):
    damage-=minus[i]
    monster[i]=max(0,monster[i]-damage)
    if(monster[i]==0):
        continue
    cnt=math.ceil(monster[i]/A)
    monster[i]=0
    ans+=cnt
    b=bisect.bisect_left(X,X[i]+2*D+1)
    minus[b]+=cnt*A
    damage+=A*cnt
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline
from collections import deque

def main():
    N, D, A = map(int, input().split())
    monsters = sorted([list(map(int, input().split())) for _ in range(N)])
    
    for i in range(N):
        monsters[i][1] = (monsters[i][1] + A - 1) // A
    
    attacks = deque([]) 
    ans = 0
    atk = 0
    for i in range(N):
        atk_this = monsters[i][1]
        while attacks and monsters[i][0] > attacks[0][0]:
            _, atk_ = attacks.popleft()
            atk -= atk_
        if atk_this - atk > 0:
            ans += atk_this - atk
            attacks.append((monsters[i][0]+2*D, atk_this-atk))
            atk += atk_this - atk
    print(ans)
    
if __name__ == '__main__':
    main()

Solution (Python):
n, d, a = map(int, input().split())
xh = []
for _ in range(n):
    x, h = map(int, input().split())
    xh.append((x, h))

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

def bisect(x):
    ok = n
    ng = -1
    while abs(ok-ng)>1:
        mid = (ok+ng)//2
        if xh[mid][0]>x:
            ok = mid
        else:
            ng = mid
    return ok

out = [0]*(n+1)
ans = 0
accu = 0
for ind, (x, h) in enumerate(xh):
    accu -= out[ind]
    h -= accu
    if h<=0:
        continue
    ans += (h+a-1)//a
    accu += ((h+a-1)//a)*a
    out[bisect(x+2*d)] += ((h+a-1)//a)*a
print(ans)

Solution (Python):
from collections import deque
n,d,a = map(int,input().split())
f = [list(map(int,input().split()))for i in range(n)]
queue = deque()
f.sort()
tot = 0
ans = 0
for i in range(n):
    x = f[i][0]
    h = f[i][1]
    while queue and queue[0][0] < x:
        now = queue.popleft()
        tot -= now[1]
    h -= tot
    if h > 0:
        num = (h+a-1)//a
        ans += num
        damage = num*a
        tot+=damage
        queue.append((x+2*d,damage))
print(ans)

Solution (Python):

import math
import sys
import bisect
def LI(): return [int(x) for x in sys.stdin.buffer.readline().split()]
def I(): return int(sys.stdin.buffer.readline())
def LIR(n):
    return [LI() for i in range(n)]

class SegmentTree:
    def __init__(self, size, f=lambda x,y : x+y, default=0):
        self.size = 2**(size-1).bit_length()
        self.default = default
        self.dat = [default]*(self.size*2)
        self.f = f

    def update(self, i, x):
        i += self.size
        self.dat[i] = x
        while i > 0:
            i >>= 1
            self.dat[i] = self.f(self.dat[i*2], self.dat[i*2+1])

    def get(self, a, b=None):
        if b is None:
            b = a + 1
        l, r = a + self.size, b + self.size
        lres, rres = self.default, self.default
        while l < r:
            if l & 1:
                lres = self.f(lres, self.dat[l])
                l += 1

            if r & 1:
                r -= 1
                rres = self.f(self.dat[r], rres)
            l >>= 1
            r >>= 1
        res = self.f(lres, rres)
        return res

def solve():
    n,d,a = LI()
    g = LIR(n)
    g.sort()
    X = [i for (i,_) in g]
    s = SegmentTree(n)
    ans = 0
    for i in range(n):
        x = g[i][0]
        j = bisect.bisect_left(X,x-2*d)
        h = g[i][1]-s.get(j,i)
        if h <= 0:
            continue
        k = math.ceil(h/a)
        ans += k
        s.update(i,k*a)
    print(ans)
    return


if __name__ == "__main__":
    solve()

Solution (Python):

import math
import sys
import bisect
def LI(): return [int(x) for x in sys.stdin.buffer.readline().split()]
def I(): return int(sys.stdin.buffer.readline())
def LIR(n):
    return [LI() for i in range(n)]

class SegmentTree:
    def __init__(self, size, f=lambda x,y : x+y, default=0):
        self.size = 2**(size-1).bit_length()
        self.default = default
        self.dat = [default]*(self.size*2)
        self.f = f

    def update(self, i, x):
        i += self.size
        self.dat[i] = x
        while i > 0:
            i >>= 1
            self.dat[i] = self.f(self.dat[i*2], self.dat[i*2+1])

    def get(self, a, b=None):
        if b is None:
            b = a + 1
        l, r = a + self.size, b + self.size
        lres, rres = self.default, self.default
        while l < r:
            if l & 1:
                lres = self.f(lres, self.dat[l])
                l += 1

            if r & 1:
                r -= 1
                rres = self.f(self.dat[r], rres)
            l >>= 1
            r >>= 1
        res = self.f(lres, rres)
        return res

def solve():
    n,d,a = LI()
    g = LIR(n)
    g.sort()
    X = [i for (i,_) in g]
    s = SegmentTree(n)
    ans = 0
    for i in range(n):
        x = g[i][0]
        j = bisect.bisect_left(X,x-2*d)
        h = g[i][1]-s.get(j,i+1)
        if h <= 0:
            continue
        k = math.ceil(h/a)
        ans += k
        s.update(i,k*a)
    print(ans)
    return


if __name__ == "__main__":
    solve()

Solution (Python):
from heapq import heappop, heappush

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

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

ans = 0
bomb = []
SUMD = 0 
for x, h in XH:
    while bomb:
        right, damage = heappop(bomb)
        if right < x:
            SUMD -= damage
        else:
            heappush(bomb, (right, damage))
            break
    h -= SUMD
    if h > 0:
        cnt = (h + A - 1) // A
        SUMD += cnt * A
        heappush(bomb, (x + 2 * D, cnt * A))
        ans += cnt

print(ans)

Solution (Python):
import math
import collections
N, D, A = map(int, input().split())

XH = [tuple(map(int, input().split())) for i in range(N)]
XH.sort()
q = collections.deque()
c = 0
ans = 0
for x, h in XH:
    while(q and q[0][0] < x):
        c -= q[0][1]
        q.popleft()
    h -= c * A
    if h < 0:
        h = 0
    ans += math.ceil(h/A)
    c += math.ceil(h/A)

    q.append((x+2*D, math.ceil(h/A)))

print(ans)

Solution (Python):
def examA():
    N = I()
    L = LI()
    L.sort()
    if sum(L)<=L[-1]*2:
        print("No")
    else:
        print("Yes")
    return

def examB():
    N, M = LI()
    A = [LI()for _ in range(N)]
    A.sort(key=lambda x:x[0])
    ans = 0
    for a,b in A:
        if M<=b:
            ans += a*M
            break
        ans += a*b
        M -= b
    print(ans)
    return

def examC():
    N = I()
    S = [SI()for _ in range(N)]
    D = defaultdict(int)
    for s in S:
        cur = []
        for i,j in Counter(s).items():
            cur.append((i,j))
        
        cur.sort()
        cur = tuple(cur)
        D[cur] += 1
    ans = 0
    for d in D.values():
        ans += (d-1)*d//2
    print(ans)
    return

def examD():
    N, K = LI()
    A = LI()
    S = [0]*(N+1)
    for i in range(N):
        S[i+1] = S[i]+A[i]
    ans = 0
    for i in range(N):
        l = i-1; r = N
        if S[-1]-S[i]<K:
            break
        while(r-l>1):
            now = (l+r)//2
            if S[now]-S[i]<K:
                l = now
            else:
                r = now
        
        ans += (N-r+1)
    print(ans)
    return

def examE():
    
    class SegmentTree:
        def __init__(self, n, ele, segfun):
            
            self.ide_ele = ele
            self.segfun = segfun
            
            self.n = n
            self.N0 = 1 << n.bit_length()
            self.data = [self.ide_ele] * (self.N0 * 2)

        def update_add(self, l, r, val):
            l += self.N0
            r += self.N0
            while l < r:
                if l & 1:
                    self.data[l] += val
                    l += 1
                if r & 1:
                    self.data[r - 1] += val
                    r -= 1
                l //= 2
                r //= 2

        def update(self, l, r, val):
            l += self.N0
            r += self.N0
            while l < r:
                if l & 1:
                    self.data[l] = self.segfun(self.data[l], val)
                    l += 1
                if r & 1:
                    self.data[r - 1] = self.segfun(self.data[r - 1], val)
                    r -= 1
                l //= 2
                r //= 2

        def query(self, i):
            i += len(self.data) // 2
            ret = self.data[i]
            while i > 0:
                i //= 2
                ret = self.segfun(ret, self.data[i])
            return ret

    N, D, A = LI()
    X = [LI()for _ in range(N)]
    X.sort()
    L = [0]*N
    for i in range(N):
        L[i] = X[i][0]
    S = SegmentTree(N,0,lambda a, b: a+b)
    ans = 0
    for i,[x,h] in enumerate(X):
        H = h - S.query(i)
        if H<=0:
            continue
        ne = bisect.bisect_right(L,x+2*D)
        
        need = (H-1)//A + 1
        S.update(i,ne,need*A)
        ans += need
    print(ans)
    return

def examF():
    ans = 0
    print(ans)
    return

import sys,bisect,itertools,heapq,math,random
from copy import deepcopy
from heapq import heappop,heappush,heapify
from collections import Counter,defaultdict,deque
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
def I(): return int(readline())
def LI(): return list(map(int,readline().split()))
def LSI(): return list(map(str,sys.stdin.readline().split()))
def LS(): return sys.stdin.readline().split()
def SI(): return sys.stdin.readline().strip()
global mod,mod2,inf,alphabet,_ep
mod = 10**9 + 7
mod2 = 998244353
inf = 10**18
_ep = 10**(-12)
alphabet = [chr(ord('a') + i) for i in range(26)]

sys.setrecursionlimit(10**7)

if __name__ == '__main__':
    examE()

"""
142
12 9 1445 0 1
asd dfg hj o o
aidn
"""

Solution (Python):
import sys
input = sys.stdin.readline
import collections
from collections import deque
n,d,a= map(int, input().split())
x= [list(map(int, input().split())) for i in range(n)]

x.sort()
for i in range(n):
    x[i][1]=-(-x[i][1]//a)



qq=deque([])
ans=0
atk=0
for i in range(n):
    w=x[i][1]
    
    while len(qq)>0 and x[i][0] > qq[0][0]:
        atk-=qq[0][1]
        qq.popleft()

    if w-atk>0:
        ans+=w-atk
        
        qq.append([x[i][0]+2*d,w-atk])
        atk += w - atk
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline
import bisect
import collections
from collections import deque
n,d,a= map(int, input().split())
x= [list(map(int, input().split())) for i in range(n)]

x.sort()
y=[]
for i in range(n):
    y.append(x[i][0])
    x[i][1]=-(-x[i][1]//a)



qq=deque([])
ans=0
atk=0
for i in range(n):
    w=x[i][1]
    
    while len(qq)>0 and i > qq[0][0]:
        atk-=qq[0][1]
        qq.popleft()

    if w-atk>0:
        ans+=w-atk
        q=bisect.bisect_right(y,x[i][0]+2*d)-1
        
        qq.append([q,w-atk])
        atk += w - atk
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline
n, d, a = map(int, input().split())
xh = sorted([tuple(map(int, input().split()))for _ in range(n)])
INF = 10**18
x_list = [x for x, h in xh]
x_list.append(INF)

end_idx_list = [0]*n
idx = 0
for i in range(n):
    while True:
        if x_list[i]+2*d < x_list[idx]:
            end_idx_list[i] = idx
            break
        idx += 1

damage = [0]*(n+1)
ans = 0
for i in range(n):
    x, h = xh[i]
    h -= damage[i]
    if 0 < h:
        cnt = -(-h//a)
        ans += cnt
        damage[i] += cnt*a
        end_idx = end_idx_list[i]
        damage[end_idx] -= cnt*a

    damage[i+1] += damage[i]
print(ans)

Solution (Python):
import sys
import bisect
input = sys.stdin.readline
n, d, a = map(int, input().split())
xh = sorted([tuple(map(int, input().split()))for _ in range(n)])
x_list = [x for x, h in xh]

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

print(ans)