Buggy python submission (verdict: Time Limit Exceeded):
N, D, A = 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(XH, [x+D*2+1, -1])
    cnt[j] += n*A
    res += n*A
    ans+=n
print(ans)
    





Fixed submission:

N, D, A = 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)

Buggy python submission (verdict: Runtime Error):

N, D, A = 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)]
S = SegmentTree(N, 0, lambda x, y:x+y)
ans = 0
res = 0
from bisect import bisect
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(X, x+D*2+1)
    cnt[j]+=n*A
    res+= n*A
    ans+=n
print(ans)
    





Fixed submission:

N, D, A = 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)

Buggy python submission (verdict: Time Limit Exceeded):
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 = 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)
    





Fixed submission:

N, D, A = 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)