Problem:
 Score : 600 points    Problem Statement There are N robots numbered 1 to N placed on a number line. Robot i is placed at coordinate X_i . When activated, it will travel the distance of D_i in the positive direction, and then it will be removed from the number line. All the robots move at the same speed, and their sizes are ignorable.  Takahashi, who is a mischievous boy, can do the following operation any number of times (possibly zero) as long as there is a robot remaining on the number line.   Choose a robot and activate it. This operation cannot be done when there is a robot moving.   While Robot i is moving, if it touches another robot j that is remaining in the range [X_i, X_i + D_i) on the number line, Robot j also gets activated and starts moving. This process is repeated recursively.  How many possible sets of robots remaining on the number line are there after Takahashi does the operation some number of times? Compute this count modulo 998244353 , since it can be enormous.      Constraints  1 \leq N \leq 2 \times 10^5  -10^9 \leq X_i \leq 10^9  1 \leq D_i \leq 10^9  X_i \neq X_j (i \neq j)  All values in input are integers.         Input Input is given from Standard Input in the following format:  N  X_1  D_1  :  X_N  D_N       Output Print the number of possible sets of robots remaining on the number line, modulo 998244353 .        Sample Input 1 2
1 5
3 3      Sample Output 1 3  There are three possible sets of robots remaining on the number line: \{1, 2\} , \{1\} , and \{\} .  These can be achieved as follows:    If Takahashi activates nothing, the robots \{1, 2\} will remain.    If Takahashi activates Robot 1 , it will activate Robot 2 while moving, after which there will be no robots on the number line. This state can also be reached by activating Robot 2 and then Robot 1 .    If Takahashi activates Robot 2 and finishes doing the operation, the robot \{1\} will remain.         Sample Input 2 3
6 5
-1 10
3 3      Sample Output 2 5  There are five possible sets of robots remaining on the number line: \{1, 2, 3\} , \{1, 2\} , \{2\} , \{2, 3\} , and \{\} .       Sample Input 3 4
7 10
-10 3
4 3
-4 3      Sample Output 3 16  None of the robots influences others.       Sample Input 4 20
-8 1
26 4
0 5
9 1
19 4
22 20
28 27
11 8
-3 20
-25 17
10 4
-18 27
24 28
-11 19
2 27
-2 18
-1 12
-24 29
31 29
29 7      Sample Output 4 110  Remember to print the count modulo 998244353 .

Solution (Python):
import sys
from bisect import bisect_left as bl
input = sys.stdin.readline
N = int(input())
mod = 998244353
a = []
xs = [0] * N
for _ in range(N):
  x, d = map(int, input().split())
  a.append((x, d))
a.sort()
for i in range(N): xs[i] = a[i][0]

class SegTree:
  def segfunc(self, x, y):
    return max(x, y)
  def __init__(self, n, ide_ele, init_val):
    
    self.ide_ele = ide_ele
    
    self.num = 2 ** (n - 1).bit_length()
    self.seg = [self.ide_ele] * 2 * self.num
    
    for i in range(n):
      self.seg[i + self.num - 1] = init_val[i]    
    
    for i in range(self.num - 2, -1, -1) :
      self.seg[i] = self.segfunc(self.seg[2 * i + 1], self.seg[2 * i + 2]) 
  def update(self, k, x):
    k += self.num - 1
    self.seg[k] = x
    while k + 1:
      k = (k - 1) // 2
      self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2]) 
  def query(self, p, q):
    if q <= p:
      return self.ide_ele
    p += self.num - 1
    q += self.num - 2
    res = self.ide_ele
    while q - p > 1:
      if p & 1 == 0:
        res = self.segfunc(res, self.seg[p])
      if q & 1 == 1:
        res = self.segfunc(res, self.seg[q])
        q -= 1
      p = p // 2
      q = (q - 1) // 2
    if p == q:
      res = self.segfunc(res, self.seg[p])
    else:
      res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])
    return res

seg = SegTree(N, 0, [0] * N)

for l in range(N - 1, -1, -1):
  r = bl(xs, a[l][0] + a[l][1])
  mx = max(l, seg.query(l, r))
  seg.update(l, mx)
  

dp = [0] * (N + 1)
dp[0] = 1
for i in range(N):
  dp[i + 1] += dp[i]
  dp[i + 1] %= mod
  dp[seg.query(i, i + 1) + 1] += dp[i]
  dp[i + 1] %= mod
print(dp[-1])

Solution (Python):
import sys
sys.setrecursionlimit(2147483647)
INF = 1 << 60
MOD = 998244353
input = lambda:sys.stdin.readline().rstrip()

class SegmentTree(object):
    def __init__(self, A, dot, unit):
        n = 1 << (len(A) - 1).bit_length()
        tree = [unit] * (2 * n)
        for i, v in enumerate(A):
            tree[i + n] = v
        for i in range(n - 1, 0, -1):
            tree[i] = dot(tree[i << 1], tree[i << 1 | 1])
        self._n = n
        self._tree = tree
        self._dot = dot
        self._unit = unit

    def __getitem__(self, i):
        return self._tree[i + self._n]

    def update(self, i, v):
        i += self._n
        self._tree[i] = v
        while i != 1:
            i >>= 1
            self._tree[i] = self._dot(self._tree[i << 1], self._tree[i << 1 | 1])

    def add(self, i, v):
        self.update(i, self[i] + v)

    def sum(self, l, r):
        l += self._n
        r += self._n
        l_val = r_val = self._unit
        while l < r:
            if l & 1:
                l_val = self._dot(l_val, self._tree[l])
                l += 1
            if r & 1:
                r -= 1
                r_val = self._dot(self._tree[r], r_val)
            l >>= 1
            r >>= 1
        return self._dot(l_val, r_val)

from bisect import bisect_left
def resolve():
    n = int(input())
    XD = [tuple(map(int, input().split())) for _ in range(n)]
    XD.sort()
    X = [xd[0] for xd in XD]

    tree = SegmentTree([-INF] * n, max, -INF)
    for i in range(n - 1, -1, -1):
        x, d = XD[i]
        j = bisect_left(X, x + d)
        tree.update(i, max(j, tree.sum(i + 1, j)))

    dp = [0] * (n + 1)
    dp[n] = 1
    for i in range(n - 1, -1, -1):
        dp[i] += dp[i + 1]
        dp[i] += dp[tree[i]]
        dp[i] %= MOD
        
    print(dp[0])
resolve()

Solution (Python):
mod = 998244353
from bisect import bisect_left as bisect
from operator import itemgetter
N = int(input())
XD = [list(map(int,input().split())) for _ in range(N)]
XD.sort(key=itemgetter(0))
X = [XD[i][0] for i in range(N)]
D = [XD[i][1] for i in range(N)]

N0 = 2**(N-1).bit_length()
INF = 2**31-1
data = [INF]*(4*N0)

def update(k, x):
    k += N0-1
    data[k] = x
    while k >= 0:
        k = (k - 1) // 2
        data[k] = min(data[2*k+1], data[2*k+2])

def query(l, r):
    L = l + N0; R = r + N0
    s = INF
    while L < R:
        if R & 1:
            R -= 1
            s = min(s, data[R-1])

        if L & 1:
            s = min(s, data[L-1])
            L += 1
        L >>= 1; R >>= 1
    return s

for i in range(N-1,-1,-1):
    x,d = XD[i]
    j = bisect(X,x+d)
    update(i,-i)
    update(i,query(i,j))

dp = [1]*(N+1)

for i in range(N-1,-1,-1):
    j = -query(i,i+1)
    dp[i] = dp[i+1] + dp[j+1]
    dp[i] %= mod

print(dp[0])

Solution (Python):
import sys
from bisect import bisect_left,bisect_right
input = sys.stdin.readline
ide = 0
def func(a,b):
  return max(a,b)
class SegmentTree:
  def __init__(self,ls,commutative = True):
    if commutative == True:
      self.n = len(ls)
      self.tree = [ide for i in range(self.n)]+ls
    else:
      self.n = 2**((len(ls)-1).bit_length())
      self.tree = [ide for i in range(self.n)]+ls+[ide for i in range(self.n-len(ls))]
    for i in range(1,self.n)[::-1]:
      self.tree[i] = func(self.tree[i<<1|0],self.tree[i<<1|1])
  def getall(self):
    return self.tree[1]
  def get(self,l,r):
    lret = ide
    rret = ide
    l += self.n
    r += self.n
    while l < r:
      if l&1:
        lret = func(lret,self.tree[l])
        l += 1
      if r&1:
        rret = func(self.tree[r-1],rret)
      l >>= 1
      r >>= 1
    ret = func(lret,rret)
    return ret
  def update(self,i,x):
    i += self.n
    self.tree[i] = x
    while i > 1:
      i >>= 1
      self.tree[i] = func(self.tree[i<<1|0],self.tree[i<<1|1])
n = int(input())
xd = [list(map(int,input().split())) for i in range(n)]
mod = 998244353
xd.sort()
xls = list(zip(*xd))[0]
rls = [0]*n
st = SegmentTree(rls)
for i in range(n)[::-1]:
  idx = bisect_left(xls,xd[i][0]+xd[i][1])-1
  x = st.get(i,idx+1)
  st.update(i,max(i,x))
dp = [0]*(n)
dp[-1] = 2
for i in range(n-1)[::-1]:
  x = st.get(i,i+1)
  if x == n-1:
    dp[i] = dp[i+1]+1
  else:
    dp[i] = dp[i+1]+dp[x+1]
  dp[i] %= mod
print(dp[0])

Solution (Python):
mod = 998244353

n = 0
x = []
d = []

def search(s):
    lo = 0
    hi = n - 1
    while lo <= hi:
        mid = (lo + hi) // 2
        if s > x[mid]:
            lo = mid + 1
        elif s < x[mid]:
            hi = mid - 1
        else:
            return mid
    return max(lo, hi)


if __name__ == "__main__":
    xd = []
    n = int(input())
    for i in range(n):
        xi, di = map(int, input().split())
        xd.append((xi, di))

    xd.sort()
    x = list(map(lambda x: x[0], xd))
    d = list(map(lambda x: x[1], xd))

    dp = [0] * (n+1)
    dp[-1] = 1
    next = [0] * n

    st = []
    st.append((n, 2e9))

    for i in range(n-1, -1, -1):

        while st[-1][1] < x[i] + d[i]:
            st.pop()
        next[i] = st[-1][0]
        st.append((i, x[i]))

    for i in range(n - 1, -1, -1):
        dp[i] = (dp[next[i]] + dp[i + 1]) % mod
    
    print(dp[0])

Solution (Python):
import sys
input = sys.stdin.readline
N = int(input())
XD = [tuple(map(int,input().split())) for i in range(N)]
XD.sort()
MOD = 998244353
ns = [-1] * N

for i,(x,d) in reversed(list(enumerate(XD))):
    tmp = i
    while tmp < N-1:
        nx,_ = XD[tmp+1]
        if nx < x+d:
            tmp = ns[tmp+1]
        else:
            break
    ns[i] = tmp

dp = [0] * (N+1)
dp[N] = 1
for i in range(N-1,-1,-1):
    dp[i] = (dp[i+1] + dp[ns[i]+1]) % MOD
print(dp[0])

Solution (Python):
def main():
    from collections import deque
    import sys
    sys.setrecursionlimit(10**7)
    input = sys.stdin.readline
    n = int(input())
    X = sorted([list(map(int,input().split())) for i in range(n)])
    mod = 998244353
    e = [[] for i in range(n)]

    def dfs(x):
        count = 1

        for i in e[x]:
            count *= dfs(i)
            count %= mod
        return count+1

    q = deque([])

    for i in range(n-1,-1,-1):
        a,b = X[i]
        while q and q[0][0] < a+b:
            e[i].append(q[0][1]) 
            q.popleft()
        q.appendleft([a,i])

    ans = 1
    for i,j in q:
        ans *= dfs(j)
        ans %= mod
    print(ans)
if __name__ == "__main__":
    main()

Solution (Python):
import sys
from operator import itemgetter
from bisect import bisect_left, bisect_right
input = sys.stdin.readline
MOD = 998244353


class SegmentTree1():
    """
    1-indexed Segment Tree
    """
    def __init__(self, n_, ele_id, op_func):
        self.n = 1 << (n_ - 1).bit_length()  
        self.data = [ele_id] * (2 * self.n)  
        self.ele_id = ele_id  
        self.op_func = op_func  

    def __getitem__(self, i):
        return self.data[i + self.n]

    def build(self, data_init):
        for i in range(len(data_init)):
            self.data[i + self.n] = data_init[i]  
        for i in reversed(range(self.n)):
            self.data[i] = self.op_func(self.data[2 * i], self.data[2 * i + 1])

    def update(self, i, x):
        
        i += self.n
        self.data[i] = x
        while i > 1:
            i = i >> 1  
            self.data[i] = self.op_func(self.data[2 * i], self.data[2 * i + 1])

    def query(self, l, r):
        
        l += self.n
        r += self.n
        ret = self.ele_id
        while l < r:
            if l & 1:  
                ret = self.op_func(ret, self.data[l])
                l += 1
            if r & 1:  
                r -= 1
                ret = self.op_func(ret, self.data[r])
            
            l = l >> 1
            r = r >> 1
        return ret


n = int(input())
robot = [tuple(map(int, input().split())) for _ in range(n)]
robot.sort(key=itemgetter(0))
x = [robot[i][0] for i in range(n)]


dp = [0] * n
dp[n - 1] = n - 1

st_rmq = SegmentTree1(n, 0, max)
st_rmq.update(n - 1, dp[n - 1])
for i in reversed(range(n - 1)):
    r = bisect_left(x, x[i] + robot[i][1])
    dp[i] = max(i, st_rmq.query(l=i + 1, r=r))
    st_rmq.update(i, dp[i])




dp2 = [0] * (n + 1)
dp2[n] = 1
for i in reversed(range(n)):
    dp2[i] = dp2[i + 1] + dp2[dp[i] + 1]
    dp2[i] %= MOD


print(dp2[0])

Solution (Python):
def main():
    mod = 998244353
    n = int(input())
    ab = sorted([tuple(map(int, input().split())) for _ in [0]*n])
    next_idx = [-1]*n
    for i in range(n-1, -1, -1):
        dist = sum(ab[i])
        now = i
        while now < n-1:
            a1, b1 = ab[now+1]
            if a1 < dist:
                now = next_idx[now+1]
            else:
                break
        next_idx[i] = now
    dp = [0]*(n+1)
    dp[n] = 1
    for i in range(n-1, -1, -1):
        dp[i] = (dp[i+1]+dp[next_idx[i]+1]) % mod
    print(dp[0])
 
 
main()

Solution (Python):
import bisect


class SegTree:
    def __init__(self, n):
        self.n = n
        self.s = 1
        while self.s < self.n:
            self.s <<= 1
        self.mins = [1 << 30] * (self.s * 2)

    def update(self, i, val):
        i += self.s
        self.mins[i] = val
        i >>= 1
        while i:
            self.mins[i] = min(self.mins[i * 2], self.mins[i * 2 + 1])
            i >>= 1

    def min(self, l, r):
        l += self.s
        r += self.s
        res = self.mins[0]
        while l <= r:
            if l & 1:
                res = min(res, self.mins[l])
                l += 1
            if not r & 1:
                res = min(res, self.mins[r])
                r -= 1
            l >>= 1
            r >>= 1
        return res


MOD = 998244353
N = int(input())
robots = []
for _ in range(N):
    x, d = map(int, input().split())
    robots.append((-x, -d))
robots.sort()
dp = [0] * (N + 1)
dp[0] = 1
st = SegTree(N)
for i, (x, d) in enumerate(robots):
    lo = bisect.bisect_right(robots, (x + d, 0), hi=i)
    lo = min(lo, st.min(lo, i))
    st.update(i, lo)
    dp[i + 1] += (dp[i] + dp[lo]) % MOD
print(dp[-1])

Solution (Python):
MOD = 998244353
N = int(input())
robots = []
for _ in range(N):
    x, d = map(int, input().split())
    robots.append((x, d))
robots.sort(reverse=True)
dp = [0] * (N + 1)
los = [N] * (N + 1)
dp[0] = 1
los[0] = 0
for i, (x, d) in enumerate(robots):
    lo = i
    while lo > 0 and robots[lo - 1][0] < x + d:
        lo = los[lo]
    los[i + 1] = lo
    dp[i + 1] += (dp[i] + dp[lo]) % MOD
print(dp[-1])

Solution (Python):
import sys
sys.setrecursionlimit(10**9)

mod = 998244353


def init_max(init_max_val, n):
    
    for i in range(n):
        seg_max[i+num_max-1]=init_max_val[i]
    
    for i in range(num_max-2,-1,-1) :
        seg_max[i]=max(seg_max[2*i+1],seg_max[2*i+2])

def update_max(k,x):
    k += num_max-1
    seg_max[k] = x
    while k:
        k = (k-1)//2
        seg_max[k] = max(seg_max[k*2+1],seg_max[k*2+2])

def query_max(p,q):
    if q<=p:
        return ide_ele_max
    p += num_max-1
    q += num_max-2
    res=ide_ele_max
    while q-p>1:
        if p&1 == 0:
            res = max(res,seg_max[p])
        if q&1 == 1:
            res = max(res,seg_max[q])
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res = max(res,seg_max[p])
    else:
        res = max(max(res,seg_max[p]),seg_max[q])
    return res


ide_ele_max = -1


num_max = 1 << 18
seg_max=[ide_ele_max]*2*num_max



N = int(input())
tmpX = []
for i in range(N):
    x, d = list(map(int, input().split()))
    tmpX.append((x, d))
tmpX.sort()


X, D = [0] * N, [0] * N
for i in range(N):
    X[i] = tmpX[i][0]
    D[i] = tmpX[i][1]

to = [0] * N
for i in range(N):
    to[i] = i
init_max(to, N)

for i in range(N-1, -1, -1):
    ok = i
    ng = N
    while ng - ok > 1:
        mid = (ng + ok) // 2
        if X[i] + D[i] > X[mid]:
            ok = mid
        else :
            ng = mid
    to[i] = query_max(i, ok+1)
    update_max(i, to[i])

dp = [0] * (N+1)
dp[0] = 1
for i in range(N):
    dp[i+1] += dp[i]
    dp[i+1] %= mod
    dp[to[i]+1] += dp[i]
    dp[to[i]+1] %= mod
print(dp[N])

Solution (Python):
from collections import deque


n = int(input())
info = [list(map(int, input().split())) for i in range(n)]
info = sorted(info, reverse=True)
MOD = 998244353

dp = [0] * (n + 1)
dp[0] = 1
q = deque([])

for i in range(n):
    
    dp[i + 1] += dp[i]
    
    
    x, d = info[i]
    l, r = x, x + d
    num = 1
    while True:
        if not q:
            q.append((l, num))
            break
        tmp_l, tmp_num = q.pop()
        if r > tmp_l:
            num = tmp_num + num
        else:
            q.append((tmp_l, tmp_num))
            q.append((l, num))
            break
    num = q[-1][1]
    dp[i + 1] += dp[i + 1 - num]
    dp[i + 1] %= MOD
    
print(dp[-1])

Solution (Python):
import sys

input=sys.stdin.readline

N=int(input())
robot=[]
for i in range(N):
    x,d=map(int,input().split())
    robot.append((x,d))
mod=998244353

robot.sort()
move=[i for i in range(0,N)]
for i in range(0,N):
    x,d=robot[i]
    start=i
    end=N-1
    while end-start>1:
        test=(end+start)//2
        if x+d>robot[test][0]:
            start=test
        else:
            end=test

    if x+d>robot[end][0]:
        move[i]=end
    else:
        move[i]=start


n=N

def segfunc(x,y):
    return max(x,y)

def init(init_val):
    
    for i in range(n):
        seg[i+num-1]=init_val[i]
    
    for i in range(num-2,-1,-1) :
        seg[i]=segfunc(seg[2*i+1],seg[2*i+2])

def update(k,x):
    k += num-1
    seg[k] = x
    while k:
        k = (k-1)//2
        seg[k] = segfunc(seg[k*2+1],seg[k*2+2])

def query(p,q):
    if q<=p:
        return ide_ele
    p += num-1
    q += num-2
    res=ide_ele
    while q-p>1:
        if p&1 == 0:
            res = segfunc(res,seg[p])
        if q&1 == 1:
            res = segfunc(res,seg[q])
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res = segfunc(res,seg[p])
    else:
        res = segfunc(segfunc(res,seg[p]),seg[q])
    return res


ide_ele =0


num =2**(n-1).bit_length()
seg=[ide_ele]*2*num

chain=[i for i in range(N)]
for _ in range(0,N):
    i=N-1-_
    if move[i]==i:
        chain[i]=i
        update(i,chain[i])
    else:
        chain[i]=query(i+1,move[i]+1)
        update(i,chain[i])

dp=[0 for i in range(0,N+1)]
dp[N]=1
for j in range(0,N):
    i=N-1-j
    if chain[i]==i:
        dp[i]=(2*dp[i+1])%mod
    else:
        dp[i]=(dp[i+1]+dp[chain[i]+1])%mod

print(dp[0])

Solution (Python):
import sys
from bisect import bisect_left, bisect_right
input = lambda: sys.stdin.readline()
MOD = 998244353

class SegmentTree:
    def __init__(self, n, func=lambda x, y: min(x, y), ide=float("inf")):
        self.n = 2 ** (n-1).bit_length()
        self.data = [ide] * (self.n*2)
        self.func, self.ide = func, ide
    
    def build(self, data):
        for i, x in enumerate(data):
            self.data[self.n+i] = x
        for i in range(self.n-1, 0, -1):
            self.data[i] = self.func(self.data[i*2], self.data[i*2+1])

    def update(self, i, x):
        i += self.n
        self.data[i] = x
        while i > 1:
            i >>= 1
            self.data[i] = self.func(self.data[i*2], self.data[i*2+1])

    def query(self, l, r):
        l += self.n; r += self.n 
        res = self.ide
        while l < r:
            if l & 1:
                res = self.func(res, self.data[l])
                l += 1
            if r & 1:
                res = self.func(res, self.data[r-1])
            l >>= 1; r >>= 1
        return res
    
    def get(self, i):
        return self.data[self.n + i]

n = int(input())
xd = [tuple(map(int, input().split())) for _ in range(n)]
xd.sort()
x, d = zip(*xd)

s = SegmentTree(n, lambda x, y: max(x, y), -float("inf"))
for i in range(n)[::-1]:
    r = bisect_left(x, x[i]+d[i])
    s.update(i, max(r-1, s.query(i, r)))

dp1, dp2 = [0] * n, [0] * n
dp1[-1], dp2[-1] = 1, 1

for i in range(n-1)[::-1]:
    dp1[i] = dp1[i+1] + dp2[i+1] % MOD
    dp2[i] = dp1[s.get(i)]

print((dp1[0] + dp2[0]) % MOD)

Solution (Python):
def main():
    n = int(input())
    xd = [map(int, input().split()) for _ in range(n)]
    mod = 998244353
    INF = 10 ** 10

    xx = [(x, x + d, i) for i, (x, d) in enumerate(xd, 1)]
    xx.sort()
    c = [[] for _ in range(n + 1)]
    stack = [(INF, 0)]
    for l, r, i in xx:
        while stack[-1][0] <= l:
            stack.pop()

        ip = stack[-1][1]
        c[ip].append(i)
        stack.append((r, i))

    dp = [1] * (n + 1)
    for _, _, u in xx[::-1]:
        for v in c[u]:
            dp[u] *= dp[v]
            dp[u] %= mod

        dp[u] += 1
        dp[u] %= mod

    for v in c[0]:
        dp[0] *= dp[v]
        dp[0] %= mod

    ans = dp[0]
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
def main():
    n = int(input())
    xd = [map(int, input().split()) for _ in range(n)]
    mod = 998244353
    INF = 10 ** 10

    xx = [(x, x + d, i) for i, (x, d) in enumerate(xd, 1)]
    xx.sort()
    c = [[] for _ in range(n + 1)]
    stack = [(INF, 0)]
    for l, r, i in xx:
        while stack[-1][0] <= l:
            stack.pop()

        ip = stack[-1][1]
        c[ip].append(i)
        stack.append((r, i))

    dp = [1] * (n + 1)
    for _, _, u in xx[::-1]:
        for v in c[u]:
            dp[u] *= dp[v]
            dp[u] %= mod

        dp[u] += 1
        dp[u] %= mod

    for v in c[0]:
        dp[0] *= dp[v]
        dp[0] %= mod

    ans = dp[0]
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
def main():
    n = int(input())
    xd = [map(int, input().split()) for _ in range(n)]
    mod = 998244353
    INF = 10 ** 10

    xx = [(x, x + d, i) for i, (x, d) in enumerate(xd, 1)]
    xx.sort()
    adj = [[] for _ in range(n + 1)]
    stack = [(INF, 0)]
    for l, r, i in xx:
        while stack[-1][0] <= l:
            stack.pop()

        ip = stack[-1][1]
        adj[ip].append(i)
        stack.append((r, i))

    stack2 = [0]
    d = [-1] * (n + 1)
    d[0] = 0
    c = [[] for _ in range(n + 1)]
    order = []
    while stack2:
        u = stack2.pop()
        order.append(u)
        for v in adj[u]:
            if d[v] == -1:
                d[v] = d[u] + 1
                c[u].append(v)
                stack2.append(v)

    dp = [1] * (n + 1)
    for u in order[::-1]:
        for v in c[u]:
            dp[u] *= dp[v]
            dp[u] %= mod

        dp[u] += 1
        dp[u] %= mod

    ans = dp[0] - 1
    ans %= mod
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):

"""
Created on Sun Apr 19 15:35:41 2020

@author: ybt07
"""

class SegmentTreeMax():
    def __init__(self,n,init):
        
        
        
        
        self.offset = 2 ** ((n-1).bit_length())  
        self.tree = [init] * (2 * self.offset)
        self.init = init

    def update(self, pos, val): 
        pos += self.offset
        self.tree[pos] = val  
        while pos > 1:
            pos = pos // 2  
            
            self.tree[pos] = max(self.tree[2 * pos],self.tree[2 * pos + 1])

    def query(self, left, right): 
        
        left += self.offset
        right += self.offset
        ret = self.init  
        while left <= right:
            ret = max(ret, self.tree[right])
            right = (right - 1) // 2
            ret = max(ret, self.tree[left])
            left = (left + 1) // 2
        return ret

mod=998244353
n=int(input())
xd = [list(map(int,input().split())) for _ in range(n)]
xd = sorted(xd,key=lambda x:x[0]) 

st = SegmentTreeMax(n,0)
ranges = []

for i in range(n):
    r = xd[i][0] + xd[i][1] 
    left = -1
    right = n
    
    
    while right - left != 1:  
        mid = (left + right) // 2
        if xd[mid][0] >= r:  
            right = mid  

        else:
            left = mid  
            
    ranges.append(right - 1)  
    st.update(i, right - 1) 

for i in range(n-1,-1,-1):
    
    
    ranges[i] = st.query(i,ranges[i]) 
    st.update(i, ranges[i]) 

dp = [0] * (n+1)
dp[-1] = 1 

for i in range(n-1,-1,-1):
    j = ranges[i] + 1  
    dp[i] = dp[i+1] + dp[j] 
    dp[i] %= mod

print(dp[0])

Solution (Python):


M = 998244353

n = int(input())
r = []
for i in range(n):
    (x, d) = map(int, input().split())
    r.append((x, x + d))

r.sort()
cls = []
dp = [0 for i in range(n + 1)]
dp[n] = 1
for i in range(n - 1, -1, -1):
    ne = i + 1
    
    while cls:
        (ci, cne) = cls[-1]
        if r[ci][0] < r[i][1]:
            cls.pop()
            ne = cne
        else:
            break;
    cls.append((i, ne))
        
    dp[i] = (dp[i + 1] + dp[ne]) % M

print(dp[0])

Solution (Python):


M = 998244353

n = int(input())
r = []
for i in range(n):
    (x, d) = map(int, input().split())
    r.append((x, x + d))

r.sort()
cls = []
dp = {}
dp[n] = 1
for i in range(n - 1, -1, -1):
    ne = i + 1
    
    while cls:
        (ci, cne) = cls[-1]
        if r[ci][0] < r[i][1]:
            cls.pop()
            ne = cne
        else:
            break;
    cls.append((i, ne))
        
    dp[i] = (dp[i + 1] + dp[ne]) % M

print(dp[0])

Solution (Python):
import sys
readline = sys.stdin.readline
MOD = 998244353

class Segtree:
    def __init__(self, A, intv, initialize = True, segf = max):
        self.N = len(A)
        self.N0 = 2**(self.N-1).bit_length()
        self.intv = intv
        self.segf = segf
        if initialize:
            self.data = [intv]*self.N0 + A + [intv]*(self.N0 - self.N)
            for i in range(self.N0-1, 0, -1):
                self.data[i] = self.segf(self.data[2*i], self.data[2*i+1]) 
        else:
            self.data = [intv]*(2*self.N0)
        
    def update(self, k, x):
        k += self.N0
        self.data[k] = x
        while k > 0 :
            k = k >> 1
            self.data[k] = self.segf(self.data[2*k], self.data[2*k+1])
    
    def query(self, l, r):
        L, R = l+self.N0, r+self.N0
        s = self.intv
        while L < R:
            if R & 1:
                R -= 1
                s = self.segf(s, self.data[R])
            if L & 1:
                s = self.segf(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s
    
    def binsearch(self, l, r, check, reverse = False):
        L, R = l+self.N0, r+self.N0
        SL, SR = [], []
        while L < R:
            if R & 1:
                R -= 1
                SR.append(R)
            if L & 1:
                SL.append(L)
                L += 1
            L >>= 1
            R >>= 1
        
        if reverse:
            for idx in (SR + SL[::-1]):
                if check(self.data[idx]):
                    break
            else:
                return -1
            while idx < self.N0:
                if check(self.data[2*idx+1]):
                    idx = 2*idx + 1
                else:
                    idx = 2*idx
            return idx - self.N0
        else:
            for idx in (SL + SR[::-1]):
                if check(self.data[idx]):
                    break
            else:
                return -1
            while idx < self.N0:
                if check(self.data[2*idx]):
                    idx = 2*idx
                else:
                    idx = 2*idx + 1
            return idx - self.N0

N = int(readline())
XD = [tuple(map(int, readline().split())) for _ in range(N)]
XD.sort(key = lambda x: (x[0], -x[1]))

sXD = []
seen = set()
for x, d in XD:
    if x not in seen:
        sXD.append((x, d))
        seen.add(x)

N = len(sXD)
table = list(range(N))
T = Segtree(table, -1, initialize = True, segf = max)
X, D = map(list, zip(*sXD))
for i in range(N-1, -1, -1):
    ok = i
    ng = N
    gi = X[i] + D[i]
    while abs(ok-ng) > 1:
        med = (ok+ng)//2
        if X[med] < gi:
            ok = med
        else:
            ng = med
    table[i] = T.query(i, ok+1)
    T.update(i, table[i])

dp = [0]*(N+1)
dp[N] = 1
Dp = dp[:]
for i in range(N-1, -1, -1):
    dp[i] = Dp[table[i]+1]
    Dp[i] = (Dp[i+1] + dp[i])%MOD
print(Dp[0])

Solution (Python):
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
from bisect import bisect_right, bisect_left
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor, gamma, log
from operator import mul
from functools import reduce
from copy import deepcopy

sys.setrecursionlimit(2147483647)
INF = 10 ** 20
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
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)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 998244353

class Segtree:
    def __init__(self, A, ide_ele, segfunc, initialize=True):
        self.n = len(A)
        self.size = 2 ** (self.n - 1).bit_length()
        self.ide_ele = ide_ele
        self.segfunc = segfunc
        if initialize:
            self.data = [ide_ele] * self.size + A + [ide_ele] * (self.size - self.n)
            for i in range(self.size - 1, 0, -1):
                self.data[i] = self.segfunc(self.data[2 * i], self.data[2 * i + 1])
        else:
            self.data = [ide_ele] * (2 * self.size)

    def update(self, k, x):
        k += self.size
        self.data[k] = x
        while k:
            k = k >> 1
            self.data[k] = self.segfunc(self.data[2 * k], self.data[2 * k + 1])

    def query(self, l, r):
        L, R = l + self.size, r + self.size
        s = self.ide_ele
        while L < R:
            if R & 1:
                R -= 1
                s = self.segfunc(s, self.data[R])
            if L & 1:
                s = self.segfunc(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s


n = I()
XD = sorted(LIR(n))
X = []
D = []
for x, d in XD:
    X += [x]
    D += [d]

last = [l for l in range(n)]
st = Segtree(last, -INF, max)
for i in range(n - 2, -1, -1):
    r = bisect_left(X, X[i] + D[i])
    ret = st.query(i, r)
    st.update(i, ret)
    last[i] = ret

dp = [1] * (n + 1)
for j in range(n - 1, -1, -1):
    k = last[j]
    dp[j] = (dp[j + 1] + dp[k + 1]) % mod


print(dp[0])