Buggy python submission (verdict: Time Limit Exceeded):
import math
import bisect
N, D, A = list(map(int, input().split()))
data = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    data.append((x, h))
data = sorted(data, key=lambda x: x[0])

loc = {}
for x, h in data:
    loc[x] = bisect.bisect_right([x for x, _ in data], x+2*D)

c = 0
for i in range(N):
    x, h = data[i]
    if h <= 0:
        continue

    # 爆破回数
    attack = math.ceil(h / A)
    c += attack

    # 爆破場所
    # x + D
    for j in range(i+1, loc[x]):
        _x, _h = data[j]        
        if _x <= x + D + D:
            _h -= A * attack
            data[j] = (_x, _h)
        else:
            break

print(c)

    


Fixed submission:
import math
from collections import deque

N, D, A = list(map(int, input().split()))
data = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    data.append((x, math.ceil(h/A)))
data = sorted(data, key=lambda x: x[0])

c = 0
damage_que = deque()
attack = 0 # 有効なダメージ合計
for i in range(N):
    x, h = data[i]

    # 爆破範囲が届いていなければ削除していく
    while damage_que and x > damage_que[0][0]:
        _, a = damage_que.popleft()
        attack -= a
    
    # 有効な過去の爆破攻撃を受ける
    remain = max(h - attack, 0)
    # 0になるまで爆破    
    attack += remain
    c += remain

    # 爆破回数追加    
    damage_que.append([x+2*D, remain])

print(c)

Buggy python submission (verdict: Time Limit Exceeded):
import math
N, D, A = list(map(int, input().split()))
data = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    data.append((x, h))
data = sorted(data, key=lambda x: x[0])

c = 0
for i in range(N):
    x, h = data[i]
    if h <= 0:
        continue

    # 爆破回数
    attack = math.ceil(h / A)
    c += attack

    # 爆破場所
    # x + D
    for j in range(i+1, N):
        _x, _h = data[j]        
        if _x <= x + D + D:
            _h -= A * attack
            data[j] = (_x, _h)
        else:
            break

print(c)

    


Fixed submission:
import math
from collections import deque

N, D, A = list(map(int, input().split()))
data = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    data.append((x, math.ceil(h/A)))
data = sorted(data, key=lambda x: x[0])

c = 0
damage_que = deque()
attack = 0 # 有効なダメージ合計
for i in range(N):
    x, h = data[i]

    # 爆破範囲が届いていなければ削除していく
    while damage_que and x > damage_que[0][0]:
        _, a = damage_que.popleft()
        attack -= a
    
    # 有効な過去の爆破攻撃を受ける
    remain = max(h - attack, 0)
    # 0になるまで爆破    
    attack += remain
    c += remain

    # 爆破回数追加    
    damage_que.append([x+2*D, remain])

print(c)

Buggy python submission (verdict: Time Limit Exceeded):
import math
N, D, A = list(map(int, input().split()))
data = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    data.append((x, h))
data = sorted(data, key=lambda x: x[0])

c = 0
while N:
    if len(data) > 1:
        xl, hl = data[0]
        xr, hr = data[-1]
        if hl < hr:
            h = hr
            t = xr - D
        else:
            h = hl
            t = xl + D
    else:
        t, h = data[0]
    
    # 大きい方を殺す
    attack = math.floor(h / A)
    c += attack

    # 爆破させる場所
    # t = hl + D or hr - D    
    # abs(t - x) <= D が攻撃を受ける

    use = []
    for i in range(len(data)):
        x, h = data[i]
        if abs(t - x) <= D:
            h -= A * attack
            if h <= 0:
                N -= 1
            else:
                use.append((x, h))
        else:
            use.append((x,h))
    data = use[:]


print(c)

Fixed submission:
import math
from collections import deque

N, D, A = list(map(int, input().split()))
data = []
for _ in range(N):
    x, h = list(map(int, input().split()))
    data.append((x, math.ceil(h/A)))
data = sorted(data, key=lambda x: x[0])

c = 0
damage_que = deque()
attack = 0 # 有効なダメージ合計
for i in range(N):
    x, h = data[i]

    # 爆破範囲が届いていなければ削除していく
    while damage_que and x > damage_que[0][0]:
        _, a = damage_que.popleft()
        attack -= a
    
    # 有効な過去の爆破攻撃を受ける
    remain = max(h - attack, 0)
    # 0になるまで爆破    
    attack += remain
    c += remain

    # 爆破回数追加    
    damage_que.append([x+2*D, remain])

print(c)