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):
from bisect import bisect_right as br
from operator import itemgetter
from math import ceil
def main():
    N ,D ,A  = map(int,input().split())
    XH = [list(map(int,input().split())) for _ in range(N)]
    XH.sort(key = itemgetter(0))
    X = [x for x,h in XH]
    S = [0]*(N + 10)
    sm = 0
    for i in range(N):
        x,h = XH[i]
        right = br(X,x + 2*D) - 1
        h -= (sm - S[i-1])
        sm += max(0,ceil(h/A))*A
        S[right] += max(0,ceil(h/A))*A
        S[i] += S[i-1]
    print(sm // A)
    return

if __name__ == "__main__":
    main()

Solution (Python):
import sys
import math
from collections import defaultdict

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def II(): return map(int, input().split())
def III(): return list(map(int, input().split()))
def Line(N,num):
    if N<=0:
        return [[] for _ in range(num)]
    elif num==1:
        return [I() for _ in range(N)]
    else:
        read_all = [tuple(II()) for _ in range(N)]
        return map(list, zip(*read_all))



def solve():
    from bisect import bisect_right

    N,D,A = II()
    X,H = Line(N,2)
    
    
    class Range_BIT():
        def __init__(self, N):
            self.size = N
            self.data0 = [0]*(N+1)
            self.data1 = [0]*(N+1)

        def _add(self, data, k, x):
            while k <= self.size:
                data[k] += x
                k += k & -k

        
        def add(self, l, r, x):
            self._add(self.data0, l, -x*(l-1))
            self._add(self.data0, r, x*(r-1))
            self._add(self.data1, l, x)
            self._add(self.data1, r, -x)

        def _get(self, data, k):
            s = 0
            while k:
                s += data[k]
                k -= k & -k
            return s

        
        def query(self, l, r):
            return self._get(self.data1, r-1)*(r-1)+self._get(self.data0, r-1)\
                    -self._get(self.data1, l-1)*(l-1)-self._get(self.data0, l-1)

    
    
    from operator import itemgetter
    def index_sort(A):
        return sorted(enumerate(A),key=itemgetter(1))

    num = [math.ceil(H[i]/A) for i in range(N)]
    temp = index_sort(X)

    X2 = [temp[i][1] for i in range(N)]
    num = [num[t[0]] for t in temp]

    bit = Range_BIT(N)
    for i in range(1,N+1):
        bit.add(i,i+1,num[i-1])

    ans = 0
    for i in range(1,N+1):
        c = bit.query(i,i+1)
        if c<=0:
            continue
        p = bisect_right(X2,X2[i-1]+2*D)
        bit.add(i,p+1,-c)
        ans += c

    print(ans)

solve()

Solution (Python):
from heapq import heapify, heappush, heappop
import sys
input = sys.stdin.readline

N, D, A = map(int, input().split())
monsters = [tuple(map(int, input().split())) for _ in range(N)]
heapify(monsters)

max_H = 10**9
ans = 0
damage = 0
while monsters:
    x, h = heappop(monsters)
    if h <= max_H:
        h -= damage
        if h <= 0:
            continue
        bomb = (h+A-1) // A
        damage += bomb * A
        ans += bomb
        heappush(monsters, (x+2*D, max_H+bomb*A))
    else:
        damage -= h-max_H
print(ans)

Solution (Python):
import operator
import os
import sys
from functools import reduce

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(10 ** 9)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7





class LazySegmentTree:
    
    def __init__(self, values, fn=operator.add):
        """
        :param list values:
        :param callable fn:
        """
        
        self._id = 0
        self._size = len(values)
        self._fn = fn

        tree = [self._id] * self._size * 2
        tree[self._size:] = values[:]
        for i in reversed(range(1, self._size)):
            tree[i] = fn(tree[i << 1], tree[i << 1 | 1])
        self._tree = tree
        self._delay = [self._id] * self._size * 2

    def _add(self, k, value):
        if k < self._size:
            self._delay[k] = self._delay[k] + value
        else:
            self._tree[k] = self._tree[k] + value

    def add(self, l, r, value):
        """
        :param int l:
        :param int r:
        :param value:
        """
        l += self._size
        r += self._size
        l0, r0 = l, r
        while l < r:
            if l & 1:
                
                self._add(l, value)
                l += 1
            if r & 1:
                
                r -= 1
                self._add(r, value)
            l >>= 1
            r >>= 1
        self._update(l0)
        self._update(r0)

    def _update(self, p):
        """
        self._tree[p] の親たちを最新化する
        :param int p:
        """
        p >>= 1
        while p > 0:
            self._tree[p] = self._fn(
                self._tree[p << 1] + self._delay[p << 1],
                self._tree[p << 1 | 1] + self._delay[p << 1 | 1]
            )
            p >>= 1

    def _eval(self, p):
        """
        self._tree[p] に遅延配列から値を移す
        :param int p:
        """
        
        for h in reversed(range(1, p.bit_length())):
            k = p >> h
            self._tree[k] = self._tree[k] + self._delay[k]
            self._add(k << 1, self._delay[k])
            self._add(k << 1 | 1, self._delay[k])
            self._delay[k] = self._id

    def get(self, l, r=None):
        """
        :param int l:
        :param int|None r:
        """
        if r is None:
            self._eval(self._size + l)
            return self._tree[self._size + l]
        ret_l = []
        ret_r = []
        l += self._size
        r += self._size
        self._eval(l)
        self._eval(r)
        while l < r:
            if l & 1:
                ret_l.append(self._tree[l])
                l += 1
            if r & 1:
                r -= 1
                ret_r.append(self._tree[r])
            l >>= 1
            r >>= 1
        return reduce(self._fn, ret_l + ret_r)


N, D, A = list(map(int, sys.stdin.buffer.readline().split()))
XH = [list(map(int, sys.stdin.buffer.readline().split())) for _ in range(N)]

XH.sort()
X = []
H = []
for x, h in XH:
    X.append(x)
    H.append(h)

lr = []
r = 0
for l in range(N):
    while r < N and X[r] <= X[l] + D * 2:
        r += 1
    lr.append((l, r))

st = LazySegmentTree(values=H + [0], fn=operator.add)
ans = 0
for l, r in lr:
    h = st.get(l, l + 1)
    if h > 0:
        cnt = (h + A - 1) // A
        st.add(l, r, -cnt * A)
        ans += cnt
print(ans)

Solution (Python):
from bisect import bisect_left as bl
n,d,a=map(int,input().split())
s=sorted([list(map(int,input().split()))for i in range(n)])
c=0
p=[0]
q=[0]
for i in range(n):
    g=bl(q,s[i][0])
    s[i][1]-=a*(p[-1]-p[g-1])
    if s[i][1]>0:
        t=((s[i][1]-1)//a+1)
        c+=t
        p.append(p[-1]+t)
        q.append(s[i][0]+2*d)
print(c)

Solution (Python):
import sys
from collections import deque
from functools import lru_cache

sys.setrecursionlimit(1000000)

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()

window = deque()
windowSum = 0
total = 0
for x, h in XH:
    while window and x - window[0][0] > 2 * D:
        oldX, oldBombs = window.popleft()
        windowSum -= A * oldBombs

    h = max(0, h - windowSum)
    bombs = h // A + (1 if h % A else 0)
    total += bombs

    window.append((x, bombs))
    windowSum += A * bombs
    


print(total)

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

def main():
    N,D,A = map(int,input().split())
    XH = sorted([[int(i) for i in input().split()] for _ in range(N)],key=lambda x: x[0])

    ans = 0
    index = deque()
    damage = 0
    for i in range(N):
        
        while index:
            if index[0][0] + 2*D < XH[i][0]:
                _,c = index.popleft()
                damage -= A * c
            else:
                break
        
        
        XH[i][1] -= damage

        
        if XH[i][1] > 0:
            count = ceil(XH[i][1]/A)
            damage += count * A
            index.append([XH[i][0],count])
            ans += count

    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):
import heapq
def main():

    N, D, A = map(int, input().split())
    XH = []
    for _ in range(N):
        X, H = map(int, input().split())
        XH.append([X, H])

    if N == 1:
        x, h = XH[0]
        if h % A == 0: return h // A
        return h // A + 1

    XH.sort()
    ans = 0
    B = [[XH[0][0], XH[0][1], 0]]
    j = 0
    k = 0
    count = [0]
    while j < N or len(B) > 0:
        if len(B) > 0:
            x, h, i = heapq.heappop(B)
            h -= (count[k]- count[i])*A
            if h > 0:
                if h % A == 0: n = h // A
                else: n = h // A + 1
                ans += n
                count.append(count[-1]+n)
                while j < N and XH[j][0] <= x + 2*D:
                    heapq.heappush(B, [XH[j][0], XH[j][1], k])
                    j += 1
                k += 1
        else:
            heapq.heappush(B, [XH[j][0], XH[j][1], k])
            j += 1

    return ans

if __name__ == '__main__':
    print(main())

Solution (Python):
from math import ceil
from bisect import bisect
from operator import itemgetter
class BIT:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
 
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
 
    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

N,D,A = map(int,input().split())
XH = [list(map(int,input().split())) for _ in range(N)]
XH.sort(key=itemgetter(0))
X = [XH[i][0] for i in range(N)]
H = [XH[i][1] for i in range(N)]

bit = BIT(N)
ans = 0
for i in range(N):
    bit.add(i+1,H[i])
    bit.add(i+2,-H[i])
    h = bit.sum(i+1)
    if h>0:
        ans += ceil(h/A)
        x = -ceil(h/A)*A
        j = bisect(X,X[i]+2*D)
        bit.add(i+1,x)
        bit.add(j+1,-x)

print(ans)

Solution (Python):


import sys
from bisect import bisect_right

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = 10 ** 18
MOD = 10 ** 9 + 7

class StarrySkyTree:
    """ Starry Sky Tree(区間加算・区間最小(大)値取得) """

    def __init__(self, N, func, intv):
        self.intv = intv
        self.func = func
        LV = (N-1).bit_length()
        self.N0 = 2**LV
        self.data = [0]*(2*self.N0)
        self.lazy = [0]*(2*self.N0)

    
    def gindex(self, l, r):
        L = l + self.N0; R = r + self.N0
        lm = (L // (L & -L)) >> 1
        rm = (R // (R & -R)) >> 1
        while L < R:
            if R <= rm:
                yield R
            if L <= lm:
                yield L
            L >>= 1; R >>= 1
        while L:
            yield L
            L >>= 1

    
    def propagates(self, *ids):
        
        for i in reversed(ids):
            v = self.lazy[i-1]
            if not v:
                continue
            self.lazy[2*i-1] += v; self.lazy[2*i] += v
            self.data[2*i-1] += v; self.data[2*i] += v
            self.lazy[i-1] = 0

    def update(self, l, r, x):
        """ 区間[l,r)の値にxを加算 """

        
        
        L = self.N0 + l; R = self.N0 + r
        while L < R:
            if R & 1:
                R -= 1
                self.lazy[R-1] += x; self.data[R-1] += x
            if L & 1:
                self.lazy[L-1] += x; self.data[L-1] += x
                L += 1
            L >>= 1; R >>= 1
        
        for i in self.gindex(l, r):
            self.data[i-1] = self.func(self.data[2*i-1], self.data[2*i]) + self.lazy[i-1]

    def query(self, l, r):
        """ 区間[l,r)の最小(大)値を取得 """

        
        self.propagates(*self.gindex(l, r))
        L = self.N0 + l; R = self.N0 + r

        
        s = self.intv
        while L < R:
            if R & 1:
                R -= 1
                s = self.func(s, self.data[R-1])
            if L & 1:
                s = self.func(s, self.data[L-1])
                L += 1
            L >>= 1; R >>= 1
        return s

N, D, K = MAP()

XH = []
for i in range(N):
    x, h = MAP()
    XH.append((x, h))

XH.sort()
X, H = zip(*XH)
D = D * 2

sst = StarrySkyTree(N+1, max, 0)
ans = 0
for i, (x, h) in enumerate(XH):
    h -= sst.query(i, i+1) * K
    if h <= 0:
        continue
    cnt = ceil(h, K)
    idx = bisect_right(X, x+D) - 1
    sst.update(i, idx+1, cnt)
    ans += cnt
print(ans)

Solution (Python):
from collections import deque
n, d, a = [int(v) for v in input().split()]

X = []
for i in range(n):
    xh = [int(v) for v in input().split()]
    X.append(xh)

X.sort()


q = deque()

bomb = 0
d2 = d * 2
attack = 0
for xh in X:
    x, h = xh

    while len(q) > 0 and q[0][0] < x:
        x1, h1 = q.popleft()
        attack -= h1

    if h > attack:
        diff = h - attack
        bomb1 = diff // a
        if diff % a != 0:
            bomb1 += 1
        bomb += bomb1

        attack1 = bomb1 * a
        q.append((x+d2, attack1))
        attack += attack1

print(bomb)

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

from bisect import bisect_right

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

XH.sort()
X = [x for x, h in XH]

check = [0] * (N + 1)


index = 0
pt = XH[index][0] + 2 * D
ht = (-(-XH[index][1] // A)) * A
minus = ht
answer = -(-XH[index][1] // A)
bi = bisect_right(X, pt)
check[bi] += ht

while 1:
  flag = 1
  for i in range(index, N):
    minus -= check[i]
    XH[i][1] -= minus
    check[i] = 0
    if XH[i][1] > 0:
      index = i
      flag = 0
      break
  if flag:
    break
  pt = XH[index][0] + 2 * D
  ht = (-(-XH[index][1] // A)) * A
  minus += ht
  answer += -(-XH[index][1] // A)
  bi = bisect_right(X, pt)
  check[bi] += ht
                 
print(answer)

Solution (Python):
N, D, A = map(int, input().split())
XH = [tuple(map(int, input().split())) for _ in range(N)]
XH.sort()


ans = 0
bomb_effect = 0
bomb_i = 0
bombs = []
for x, h in XH:
    while (bomb_i < len(bombs)) and (x > bombs[bomb_i][0]):
        bomb_effect -= bombs[bomb_i][1] * A
        bomb_i += 1

    tairyoku = h - bomb_effect
    if tairyoku > 0:
        new_bomb = -((-tairyoku) // A)
        ans += new_bomb
        bombs.append((x + 2 * D + 0.5, new_bomb))
        bomb_effect += new_bomb * A

print(ans)

Solution (Python):

from collections import defaultdict,deque
from heapq import heappush, heappop
from itertools import permutations
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    n,d,a = LI()
    p = LIR(n)
    s = [0]*(n+1)
    p.sort()
    ans = 0
    X = [p[i][0] for i in range(n)]
    for i in range(n):
        x,h = p[i]
        j = bisect.bisect_left(X,x-2*d)
        if i != j:
            su = s[i-1]
            if j > 0:
                su -= s[j-1]
            h -=  su
        if h > 0:
            l = x
            k = math.ceil(h/a)
            ans += k
            s[i] = k*a
        s[i] += s[i-1]
    print(ans)
    return


if __name__ == "__main__":
    solve()

Solution (Python):
N, D, A = map(int, input().split())
XH = [[0, 0] for _ in range(N)]

for i in range(N):
    XH[i][0], XH[i][1] = map(int, input().split())

XH.sort()


ans = 0
P = 0
hist = []
j = 0
for i in range(N):
    X, H = XH[i]
    while True:
        if j >= len(hist):
            break
        if hist[j][0] >= X:
            break
        if hist[j][0] < X:
            P -= hist[j][1]
            j += 1
    
    if H - P > 0:
        if (H - P) % A == 0:
            bomb = (H - P) // A
        else:
            bomb = (H - P) // A + 1
        ans += bomb
        P += bomb * A
        hist.append((X + 2 * D, bomb * A))
    

print(ans)

Solution (Python):
from collections import deque

def updiv(a,b):
    if a % b == 0:
        return a // b
    else:
        return a // b + 1

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()

q = deque([])
qs = 0
ans = 0

for i in range(N):

    X = XH[i][0]
    H = XH[i][1]

 
    while len(q) > 0 and q[0][0] < X-D:
        po = q.popleft()
        qs -= po[1] * A

    if H - qs <= 0:
        continue
        
    else:
        pl = updiv(H-qs,A)
        qs += pl * A
        ans += pl
        q.append([X+D,pl])

print (ans)

Solution (Python):

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

XH.sort()

bombs=[]
damage=0
ans=0

for i in range(N):
    if bombs:
        while bombs[0][1]<XH[i][0]:
            b=bombs.pop(0)
            damage-=b[0]
            if not(bombs):
                break
    
    hp=XH[i][1]-damage
    num_b=-(-hp//A)
    num_b=max(num_b,0)
    bom_d=A*num_b
    bom_l=XH[i][0]+2*D
    if num_b>0:
        bombs.append([bom_d,bom_l])
        damage+=bom_d
    ans+=num_b

print(ans)

Solution (Python):

from collections import defaultdict,deque
from heapq import heappush, heappop
from itertools import permutations
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    def add(i,s):
        while i <= n:
            bit[i] += s
            i += i&-i

    def sum(i):
        res = 0
        while i > 0:
            res += bit[i]
            i -= i&-i
        return res

    n,d,a = LI()
    p = LIR(n)
    bit = [0]*(n+1)
    p.sort()
    ans = 0
    X = [p[i][0] for i in range(n)]
    for i in range(n):
        x,h = p[i]
        j = bisect.bisect_left(X,x-2*d)
        if i != j:
            su = sum(i+1)
            if j > 0:
                su -= sum(j)
            h -=  su
        if h > 0:
            l = x
            k = math.ceil(h/a)
            ans += k
            add(i+1,k*a)
    print(ans)
    return


if __name__ == "__main__":
    solve()

Solution (Python):
class SegmentTreeDual():
    def __init__(self,arr,op=lambda x,y:y if y != -1 else x,ie=-1):
        self.h = (len(arr)-1).bit_length()
        self.n = 2**self.h
        self.ie = ie
        self.op = op
        self.val = [ie for _ in range(self.n)]
        self.laz = [ie for _ in range(2*self.n)]
        for i in range(len(arr)):
            self.val[i] = arr[i]
    def propagate(self,k):
        if self.laz[k] == self.ie:
            return
        if self.n <= k:
            self.val[k-self.n] = self.op(self.val[k-self.n],self.laz[k])
            self.laz[k] = self.ie
        else:
            self.laz[(k<<1)] = self.op(self.laz[(k<<1)],self.laz[k])
            self.laz[(k<<1)+1] = self.op(self.laz[(k<<1)+1],self.laz[k])
            self.laz[k] = self.ie
    def update(self,left,right,f):
        left += self.n
        right += self.n
        for i in range(self.h)[::-1]:
            self.propagate(left>>i)
            self.propagate(right>>i)
        while right - left > 0:
            if right & 1:
                right -= 1
                self.laz[right] = self.op(self.laz[right],f)
            if left & 1:
                self.laz[left] = self.op(self.laz[left],f)
                left += 1
            left >>= 1
            right >>= 1
    def get(self,index):
        res = self.val[index]
        index += self.n
        while index>0:
            res = self.op(res,self.laz[index])
            index //= 2
        return res

import sys
input = sys.stdin.readline

import bisect

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

monster.sort()
ans = 0
X = []
H = []
for i in range(N):
    X.append(monster[i][0])
    H.append(monster[i][1])

hani = [0 for _ in range(N)]
for i in range(N):
    hani[i] = bisect.bisect_left(X,X[i]+2*D+1)

sg = SegmentTreeDual(H,lambda x,y:x+y,0)

for i in range(N):
    hp = sg.get(i)
    if hp <= 0:
        continue
    cnt = -(-hp//A)
    sg.update(i,hani[i],-A*cnt)
    ans += cnt

print(ans)

Solution (Python):




import heapq
get = lambda: int(raw_input().strip())
getl = lambda: raw_input().strip()
gets = lambda: map(int, raw_input().strip().split())
getss = lambda n: [gets() for _ in xrange(n)]


N, D, A = gets()
XH = sorted(getss(N))

bombs = []
res = cur_b = 0
for x, h in XH:
    while bombs and bombs[0][0] < x - D:
        bx, bn = heapq.heappop(bombs)
        cur_b -= bn
    h -= cur_b * A
    if h <= 0: continue
    bn = (h + A - 1) / A if A > 1 else h
    cur_b += bn
    res += bn
    heapq.heappush(bombs, [x + D, bn])
print res

Solution (Python):
from bisect import*
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)
N,d,a,*t=map(int,open(0).read().split())
N+=1
z=sorted(zip(*[iter(t)]*2))
data0=[0]*(N+1)
data1=[0]*(N+1)
y=[x for x,_ in z]
c=0
for i,(x,h)in enumerate(z,1):
    h-=query(i,i+1)
    t=0--max(0,h)//a
    j=bisect(y,x+d+d)
    add(1,j+1,t*a)
    c+=t
print(c)

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

from heapq import heappush, heappop

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

XH.sort()

ret = 0
hp = []
s = 0
for i, (x, h) in enumerate(XH) :
  while len(hp) > 0 and hp[0][0] < x - D :
    s -= heappop(hp)[1]
    
  if s > h :
    continue
  
  cnt = (h - s + A - 1) // A
  ret += cnt
  heappush(hp, (x + D, cnt * A))
  s += cnt * A

print(ret)

Solution (Python):
n,d,a = map(int,input().split())
raw = []
event = []
for i in range(n):
  x,h = map(int,input().split())
  event.append([x,0,i,h])
for i in range(n):
  tmp = event[i][0] + 2 * d
  event.append([tmp,1,i])
event.sort()

use = [0 for _ in range(n)]
now = 0
ans = 0
for j in range(2*n):
  x,d,i = event[j][:3]
  if d == 0:
    h = event[j][3]
    if h <= now * a:
      pass
    else:
      h -= now * a
      tmp = (h-1)//a+1
      now += tmp
      use[i] = tmp
      ans += tmp
  else:
    now -= use[i]
  
print(ans)

Solution (Python):
n, d, a = map(int, input().split())
loans = []
bar = 0
ans = 0
xh = sorted([tuple(map(int, input().split())) for _ in range(n)])

for x, h in xh:
    while len(loans) > 0:
        xx, dd = loans[0]
        if xx < x:
            loans.pop(0)
            bar -= dd
        else:
            break

    h -= bar
    if h > 0:
        c = h // a if h % a == 0 else ((h // a) + 1)
        ans += c
        dd = c * a
        bar += dd
        loans.append((x + 2 * d, dd))

print(ans)

Solution (Python):
def solve():
    from bisect import bisect_left, bisect_right
    import sys
    input = sys.stdin.readline

    def makeBIT(numEle):
        numPow2 = 2 ** (numEle-1).bit_length()
        data = [0] * (numPow2+1)
        return data, numPow2
    def setInit(As):
        for iB, A in enumerate(As, 1):
            data[iB] = A
        for iB in range(1, numPow2):
            i = iB + (iB & -iB)
            data[iB] -= data[i]
    def addValue(iA, A):
        iB = iA + 1
        while iB > 0:
            data[iB] += A
            iB -= iB & -iB
    def getValue(iA):
        iB = iA + 1
        ans = 0
        while iB <= numPow2:
            ans += data[iB]
            iB += iB & -iB
        return ans
    def addRangeValue(iFr, iTo, A):
        addValue(iTo, A)
        if iFr > 0:
            addValue(iFr-1, -A)

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

    XHs.sort()
    Xs = [X for X, H in XHs]
    Hs = [H for X, H in XHs]

    data, numPow2 = makeBIT(N)
    setInit(Hs)

    ans = 0
    for iL in range(N):
        H = getValue(iL)
        if H <= 0: continue
        iR = bisect_right(Xs, Xs[iL]+2*D) - 1
        num = -(-H // A)
        addRangeValue(iL, iR, -num*A)
        ans += num

    print(ans)


solve()

Solution (Python):
N,D,A = map(int,input().split())
XH = []
X = []

for i in range(N):
    x,h = map(int,input().split())
    XH.append([x,h,0])
    X.append(x)
    
XH.sort(key = lambda a:a[0])
XH.append([float('inf'),0,0])
X.sort()
X.append(float('inf'))

import bisect
ans = 0

for i in range(N):
    x,h,k = XH[i]
    dk = max(-(-(h-k*A)//A),0)
    
    ans += dk
    
    XH[i][2] += dk
    j = bisect.bisect_right(X,x+2*D)
    XH[j][2] -= dk

    XH[i+1][2] += XH[i][2]
    
print(ans)

Solution (Python):
n,d,a = map(int,input().split())
XH = []
for _ in range(n):
    x,h = map(int,input().split())
    h = (h+a-1)//a
    XH.append([x,h])
ans = 0
XH.sort()

p = 0
j = 0
data = []
for i in range(n):
    while XH[i][0] > XH[j][0] + 2*d:
        p -= data[j]
        j += 1
    if XH[i][1] > p:
        data.append(XH[i][1]-p)
        ans += XH[i][1]-p
        p = XH[i][1]
    else:
        data.append(0)

print(ans)

Solution (Python):
import sys,collections as cl,bisect as bs
sys.setrecursionlimit(100000)
input = sys.stdin.readline
mod = 10**9+7
Max = sys.maxsize
def l(): 
    return list(map(int,input().split()))
def m(): 
    return map(int,input().split())
def onem(): 
    return int(input())
def s(x): 
    a = []
    aa = x[0]
    su = 1
    for i in range(len(x)-1):
        if aa != x[i+1]:
            a.append([aa,su])
            aa = x[i+1]
            su = 1
        else:
            su += 1
    a.append([aa,su])
    return a
def jo(x): 
    return " ".join(map(str,x))
def max2(x): 
    return max(map(max,x))
def In(x,a): 
    k = bs.bisect_left(a,x)
    if k != len(a) and a[k] ==  x:
        return True
    else:
        return False
"""
def nibu(x,n,r):
    ll = 0
    rr = r
    while True:
        mid = (ll+rr)//2

    if rr == mid:
        return ll
    if (ここに評価入れる):
        rr = mid
    else:
        ll = mid+1
"""

n,d,a = m()

ppp = [0 for i in range(n)]

aaa = []
lll = []
rrr = []
co = 0
for i in range(n):
    p = l()
    aaa.append([p[0],-(-p[1]//a)])
aaa.sort()
for i in range(n):
    lll.append([aaa[i][0],aaa[i][0]+2*d])
c = 0
ll = 0
po = []
for i in range(n):
    on = aaa[i]
    for j in range(ll,n):
        if lll[j][1] < aaa[i][0] and i > j:
            c -= po[j]
        else:
            ll = j
            break
    if on[1] <= c:
        po.append(0)
        continue
    else:
        co += on[1]-c
        po.append(on[1]-c)
        c += on[1]-c
        
        """
        for j in range(i+1,n):
            if aaa[j][0] <= lll[i][1]:
                aaa[j][1] -= on[1]
            else:
                break
        """
        

print(co)

Solution (Python):

import heapq
from math import ceil
n,d,a = map(int, input().split())
xh = [list(map(int, input().split())) for _ in range(n)]
xh.sort()

res = 0
b = []
heapq.heapify(b)
r = 0
for i in range(n):
    x,h = xh[i]

    while len(b)>0 and b[0][0]<=x:
        r += b[0][1]
        heapq.heappop(b)
    c = max(ceil((h-r)/a), 0)
    res += c
    r += c*a
    
    if c>0:
        heapq.heappush(b, (x+2*d+1, -c*a))

print(res)

Solution (Python):

import sys, math, itertools, collections, bisect
input = lambda: sys.stdin.buffer.readline().rstrip().decode('utf-8')
inf = float('inf') ;mod = 10**9+7
mans = inf ;ans = 0 ;count = 0 ;pro = 1

def ceil(x,y):
  return (x-1)//y+1


def solve_binary(mid,k):
    return k < XH[mid][0]

def binary_search(s,n,k):
    ok=n
    ng=s
    while abs(ok-ng)>1:
        mid=(ok+ng)//2
        if solve_binary(mid,k):
            ok=mid
        else:
            ng=mid
    return ok

n,D,A=map(int,input().split())
XH=[tuple(map(int,input().split())) for i in range(n)]
XH.sort(key=lambda tup: tup[0])
XH.append((inf,0))
data=[0]*(n+1)
if D==0:
    for xi,hi in XH:
        count += ceil(hi,A)
        
    print(count)
    exit()
for i in range(n):
    xi,hi = XH[i]
    hi-=data[i]
    K=max(0,ceil(hi,A)*A); count += max(0,ceil(hi,A))
    data[i]+=K; data[binary_search(i,n,xi+2*D)]-=K
    data[i+1]+=data[i]
print(count)