Buggy python submission (verdict: Time Limit Exceeded):
from itertools import accumulate
import math
import bisect

n,d,a = map(int,input().split())
xh = [tuple(map(int,input().split())) for _ in range(n)]
xh.sort()
x = [xh[i][0] for i in range(n)]
h = [xh[i][1] for i in range(n)]
damage = [0]*(n+1)
point = 0

for i in range(n):
    dam = list(accumulate(damage))
    if h[i]-dam[i] <= 0:
        continue
    bi = bisect.bisect(x,2*d+x[i])
    count = math.ceil((h[i]-dam[i])/a)
    damage[i] += a*count
    damage[bi] -= a*count
    point += count

print(point)

Fixed submission:
from itertools import accumulate
import math
import bisect

n,d,a = map(int,input().split())
xh = [tuple(map(int,input().split())) for _ in range(n)]
xh.sort()
x = [xh[i][0] for i in range(n)]
h = [xh[i][1] for i in range(n)]
damage = [0]*(n+1)
point = 0

for i in range(n):
    if i != 0:
        damage[i] += damage[i-1]
    bi = bisect.bisect(x,2*d+x[i])
    count = max(math.ceil((h[i]-damage[i])/a),0)
    damage[i] += a*count
    damage[bi] -= a*count
    point += count
    
print(point)

Buggy python submission (verdict: Time Limit Exceeded):
from itertools import accumulate
import math
import bisect

n,d,a = map(int,input().split())
xh = [tuple(map(int,input().split())) for _ in range(n)]
xh.sort()
x = [xh[i][0] for i in range(n)]
h = [xh[i][1] for i in range(n)]
damage = [0]*(n+1)
point = 0

for i in range(n):
    dam = list(accumulate(damage))
    if h[i]-dam[i] <= 0:
        continue
    bi = bisect.bisect(x,2*d+x[i])
    count = math.ceil((h[i]-dam[i])/a)
    damage[i] += a*count
    damage[bi] -= a*count
    point += count

print(point)

Fixed submission:
from itertools import accumulate
import math
import bisect

n,d,a = map(int,input().split())
xh = [tuple(map(int,input().split())) for _ in range(n)]
xh.sort()
x = [xh[i][0] for i in range(n)]
h = [xh[i][1] for i in range(n)]
damage = [0]*(n+1)
point = 0

for i in range(n):
    if i != 0:
        damage[i] += damage[i-1]
    bi = bisect.bisect(x,2*d+x[i])
    count = max(math.ceil((h[i]-damage[i])/a),0)
    damage[i] += a*count
    damage[bi] -= a*count
    point += count
    
print(point)

Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
import math
from functools import lru_cache

n,d,a = map(int,input().split())
xh = [tuple(map(int,input().split())) for _ in range(n)]
xh.sort()
x = [xh[i][0] for i in range(n)]
h = [xh[i][1] for i in range(n)]
x = np.array(x)
h = np.array(h)

# どこまで巻き込めるかを調査
search = np.searchsorted(x,2*d+x,side="right")-1

@lru_cache(maxsize=None)
def keisan():
    count = 0
    for i in range(n):
        if h[i] > 0:
            count += math.ceil(h[i]/a)
            h[i:search[i]+1] -= a*math.ceil(h[i]/a)
    return count

print(keisan())

Fixed submission:
from itertools import accumulate
import math
import bisect

n,d,a = map(int,input().split())
xh = [tuple(map(int,input().split())) for _ in range(n)]
xh.sort()
x = [xh[i][0] for i in range(n)]
h = [xh[i][1] for i in range(n)]
damage = [0]*(n+1)
point = 0

for i in range(n):
    if i != 0:
        damage[i] += damage[i-1]
    bi = bisect.bisect(x,2*d+x[i])
    count = max(math.ceil((h[i]-damage[i])/a),0)
    damage[i] += a*count
    damage[bi] -= a*count
    point += count
    
print(point)

Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
import math

n,d,a = map(int,input().split())
xh = [tuple(map(int,input().split())) for _ in range(n)]
xh.sort()
x = [xh[i][0] for i in range(n)]
h = [xh[i][1] for i in range(n)]
x = np.array(x)
h = np.array(h)

# どこまで巻き込めるかを調査
search = np.searchsorted(x,2*d+x,side="right")-1
count = 0

for i in range(n):
    if h[i] > 0:
        count += math.ceil(h[i]/a)
        h[i:search[i]+1] -= a*math.ceil(h[i]/a)

print(count)

Fixed submission:
from itertools import accumulate
import math
import bisect

n,d,a = map(int,input().split())
xh = [tuple(map(int,input().split())) for _ in range(n)]
xh.sort()
x = [xh[i][0] for i in range(n)]
h = [xh[i][1] for i in range(n)]
damage = [0]*(n+1)
point = 0

for i in range(n):
    if i != 0:
        damage[i] += damage[i-1]
    bi = bisect.bisect(x,2*d+x[i])
    count = max(math.ceil((h[i]-damage[i])/a),0)
    damage[i] += a*count
    damage[bi] -= a*count
    point += count
    
print(point)