Buggy python submission (verdict: Time Limit Exceeded):
import math
def main():
    N,D,A = map(int, input().split())
    X,H = [0]*N,[0]*N
    tmp = [(0,0) for _ in range(N)]
    for i in range(N):
        tmp[i] = list(map(int, input().split()))
        tmp[i][0] -= 1
    # 座標順になるようにソートしておく
    tmp = sorted(tmp, key=lambda x:x[0])
    for i,l in enumerate(tmp): (X[i],H[i]) = l
    # 座標X[i]のモンスターはceil(H[i]/A)回攻撃すれば倒せる
    # N=5, D=2
    # 0 1 2 3 4 5 6 7 8 9 10
    # 0 5 0 2 0 0 3 3 0 0 4 (倒すのに必要な回数; 全部0にすれば終了)
    # 0 0 0 0 0 0 3 3 0 0 4 (座標3で5回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 1 (座標8で3回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 0 (座標10で1回爆破したあと)
    # ->よって5+3+1=9回が最小回数..?
    ans = 0
    for i in range(N):
        if sum(H)<=0: break
        if H[i]>0:
            # X[i]+Dで爆破を行う
            bomb = math.ceil(H[i]/A)
            ans += bomb
            for j,p in enumerate(X[i:]):
                if p<X[i]+2*D+1:
                    H[i+j] = max(0,H[i+j]-A*bomb)
                else:
                    break
    print(ans)

main()


Fixed submission:
from math import ceil
from collections import deque
def main():
    N,D,A = map(int, input().split())
    # 座標X[i]のモンスターはceil(H[i]/A)回攻撃すれば倒せる
    # N=5, D=2
    # 0 1 2 3 4 5 6 7 8 9 10
    # 0 5 0 2 0 0 3 3 0 0 4 (倒すのに必要な回数; 全部0にすれば終了)
    # 0 0 0 0 0 0 3 3 0 0 4 (座標3で5回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 1 (座標8で3回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 0 (座標10で1回爆破したあと)
    # ->よって5+3+1=9回が最小回数..?

    Monsters = sorted([list(map(int, input().split())) for i in range(N)])
    Monsters = [[x-1, ceil(h / A)] for x, h in Monsters]

    acc_damage = 0
    que = deque([])

    ans = 0
    for x, h in Monsters:
        # 期限切れの蓄積ダメージを削除
        while que and x > que[0][0]:
            limit, damage = que.popleft()
            acc_damage -= damage

        need = max(0, h - acc_damage)
        ans += need
        acc_damage += need

        if need:
            que.append([x + 2 * D, need])

    print(ans)


main()

Buggy python submission (verdict: Time Limit Exceeded):
import math
def main():
    N,D,A = map(int, input().split())
    X,H = [0]*N,[0]*N
    tmp = [(0,0) for _ in range(N)]
    for i in range(N):
        tmp[i] = list(map(int, input().split()))
        tmp[i][0] -= 1
    # 座標順になるようにソートしておく
    tmp = sorted(tmp, key=lambda x:x[0])
    for i,l in enumerate(tmp): (X[i],H[i]) = l
    # 座標X[i]のモンスターはceil(H[i]/A)回攻撃すれば倒せる
    # N=5, D=2
    # 0 1 2 3 4 5 6 7 8 9 10
    # 0 5 0 2 0 0 3 3 0 0 4 (倒すのに必要な回数; 全部0にすれば終了)
    # 0 0 0 0 0 0 3 3 0 0 4 (座標3で5回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 1 (座標8で3回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 0 (座標10で1回爆破したあと)
    # ->よって5+3+1=9回が最小回数..?
    ans = 0
    for i in range(len(X)):
        if sum(H)<=0: break
        if H[i]>0:
            # X[i]+Dで爆破を行う
            bomb = math.ceil(H[i]/A)
            ans += bomb
            for j,p in enumerate(X[i:]):
                if p<X[i]+2*D+1:
                    H[i+j] = max(0,H[i+j]-A*bomb)
                else:
                    break
    print(ans)

main()


Fixed submission:
from math import ceil
from collections import deque
def main():
    N,D,A = map(int, input().split())
    # 座標X[i]のモンスターはceil(H[i]/A)回攻撃すれば倒せる
    # N=5, D=2
    # 0 1 2 3 4 5 6 7 8 9 10
    # 0 5 0 2 0 0 3 3 0 0 4 (倒すのに必要な回数; 全部0にすれば終了)
    # 0 0 0 0 0 0 3 3 0 0 4 (座標3で5回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 1 (座標8で3回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 0 (座標10で1回爆破したあと)
    # ->よって5+3+1=9回が最小回数..?

    Monsters = sorted([list(map(int, input().split())) for i in range(N)])
    Monsters = [[x-1, ceil(h / A)] for x, h in Monsters]

    acc_damage = 0
    que = deque([])

    ans = 0
    for x, h in Monsters:
        # 期限切れの蓄積ダメージを削除
        while que and x > que[0][0]:
            limit, damage = que.popleft()
            acc_damage -= damage

        need = max(0, h - acc_damage)
        ans += need
        acc_damage += need

        if need:
            que.append([x + 2 * D, need])

    print(ans)


main()

Buggy python submission (verdict: Runtime Error):
import math
def main():
    N,D,A = map(int, input().split())
    X,H = [0]*N,[0]*N
    for i in range(N):
        x,H[i] = map(int, input().split())
        X[i] =  x-1
    # 座標X[i]のモンスターはceil(H[i]/A)回攻撃すれば倒せる
    # N=4, D=2
    # 0 1 2 3 4 5 6 7 8 9 10
    # 0 5 0 2 0 0 3 3 0 0 4 (倒すのに必要な回数; 全部0にすれば終了)
    # 0 0 0 0 0 0 3 3 0 0 4 (座標1~3のどこかで5回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 0 (座標8で4回爆破したあと)
    # ->よって5+4=9回が最小回数..?
    health = [0]*(max(X)+1)
    for i in range(N):
        health[X[i]] = math.ceil(H[i]/A)
    ans = 0
    for left in X:
        if health[left]>0:
            # left+Dで爆破を行う
            ans += health[left]
            health[left:left+2*D+1] = [max(0,p-health[left]) for p in health[left:left+2*D+1]]
    print(ans)

main()


Fixed submission:
from math import ceil
from collections import deque
def main():
    N,D,A = map(int, input().split())
    # 座標X[i]のモンスターはceil(H[i]/A)回攻撃すれば倒せる
    # N=5, D=2
    # 0 1 2 3 4 5 6 7 8 9 10
    # 0 5 0 2 0 0 3 3 0 0 4 (倒すのに必要な回数; 全部0にすれば終了)
    # 0 0 0 0 0 0 3 3 0 0 4 (座標3で5回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 1 (座標8で3回爆破したあと)
    # 0 0 0 0 0 0 0 0 0 0 0 (座標10で1回爆破したあと)
    # ->よって5+3+1=9回が最小回数..?

    Monsters = sorted([list(map(int, input().split())) for i in range(N)])
    Monsters = [[x-1, ceil(h / A)] for x, h in Monsters]

    acc_damage = 0
    que = deque([])

    ans = 0
    for x, h in Monsters:
        # 期限切れの蓄積ダメージを削除
        while que and x > que[0][0]:
            limit, damage = que.popleft()
            acc_damage -= damage

        need = max(0, h - acc_damage)
        ans += need
        acc_damage += need

        if need:
            que.append([x + 2 * D, need])

    print(ans)


main()