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):
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 > 0:
            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])

Solution (Python):
n = int(input()); arr = [list(map(int,input().split())) for _ in range(n)]

mod = 998244353
ans = 0
arr.sort(key=lambda x: x[0],reverse=True)
pos = [i[0] for i in arr]
moved = [sum(i) for i in arr]
children = [i for i in range(-1,n)]

for i in range(1,n):
    parent = moved[i]
    child = children[i]
    cmp = pos[child]
    while cmp < parent:
        child = children[child]
        if child == -1:
            break
        cmp = pos[child]
    children[i] = child
    
dp = [0] * (n+1)
dp[n] = 1
for i in range(n):
    dp[i] = dp[i-1] + dp[children[i]]
    dp[i] %= mod
    
print(dp[n-1])

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):
def main():
    mod = 998244353
    n = int(input())
    ab = [tuple(map(int, input().split())) for _ in [0]*n]
    ab.sort()
    next_a = [-1]*n
    dp = [0]*(n+1)
    dp[n] = 1
    for i in range(n-1, -1, -1):
        a0, b0 = ab[i]
        dist = a0+b0
        now = i
        while now < n-1:
            a1, b1 = ab[now+1]
            if a1 < dist:
                now = next_a[now+1]
            else:
                break
        next_a[i] = now
    for i in range(n-1, -1, -1):
        dp[i] = (dp[i+1]+dp[next_a[i]+1]) % mod
    print(dp[0] % mod)


main()

Solution (Python):
mod = 998244353
from bisect import bisect_left
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):
    j = bisect_left(X,X[i]+D[i])
    update(i,-i)
    update(i,query(i,j))

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

print(dp[0])

Solution (Python):
INF = 10**18
MOD = 998244353

N = int(input())
robots = [(-INF, INF)]

for _ in range(N):
    x, d = map(int, input().split())
    robots.append((x, x + d))

robots.sort()
stack = list()

tree = [[] for _ in range(N + 1)]

for i in range(N + 1)[::-1]:
    x, r = robots[i]
    while stack and stack[-1][0] < r:
        y, j = stack.pop()
        tree[i].append(j)
    stack.append((x, i))

stack = list()
stack.append(0)

visited = [0 for _ in range(N + 1)]
visited[0] = 1
order = [None for _ in range(N + 1)]
order[0] = 0
od = 0

while stack:
    node = stack.pop()
    for adj in tree[node]:
        if not visited[adj]:
            visited[adj] = 1
            od += 1
            order[od] = adj
            stack.append(adj)

dp = [1 for _ in range(N + 1)]

for node in order[::-1]:
    for adj in tree[node]:
        dp[node] *= dp[adj]
    dp[node] += 1
    dp[node] %= MOD

print(dp[0] - 1)

Solution (Python):
import bisect
n=int(input())
x=[]
d=[]
mod=998244353
l=[]
for i in range(n):
    l.append(list(map(int,input().split())))
l.sort(key=lambda x:x[0])
for i in range(n):
    a,b=l[i][0],l[i][1]
    x.append(a)
    d.append(b)

r=[0]*n
r[-1]=n-1
for i in range(n-2,-1,-1):
    xi=bisect.bisect_left(x,x[i]+d[i])
    xi-=1
    r[i]=xi
    
        
    
        


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+1:
        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=-10
num=2**(n-1).bit_length()
seg=[ide_ele]*2*num
init(r)
rr=[0]*n
rr[-1]=n-1
for i in range(n-2,-1,-1):
    rr[i]=query(i,r[i]+1)
    update(i,rr[i])

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

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

M = 998244353

n = int(input())
xs = [0] * n
ds = [0] * n
for i in range(n):
    x, d = (int(c) for c in input().split())
    ds[i] = d
    xs[i] = (x,i)

import sys
sys.setrecursionlimit(max(1000,n))

xs.sort()
index = [x[1] for x in xs]
xs = [x[0] for x in xs]
ds = [ds[ind] for ind in index]

def _sub(i):
    
    if i==n-1:
        return 2, n
    res = 1
    ind = i+1
    while True:
        if (xs[i]+ds[i] <= xs[ind]):
            break
        o, ind = _sub(ind)
        res *= o
        res %= M
        if ind>=n:
            break
    return res+1, ind
out = []
done = 0
while True:
    o, done = _sub(done)
    out.append(o)
    if done>=n:
        break
result = 1
for o in out:
    result *= o
    result %= M
print(result)

Solution (Python):

M = 998244353

n = int(input())
xs = [0] * n
ds = [0] * n
for i in range(n):
    x, d = (int(c) for c in input().split())
    ds[i] = d
    xs[i] = (x,i)

import sys
sys.setrecursionlimit(max(1000,n))

xs.sort()
index = [x[1] for x in xs]
xs = [x[0] for x in xs]
ds = [ds[ind] for ind in index]

def _sub(i):
    
    if i==n-1:
        return 2, n
    res = 1
    ind = i+1
    while True:
        if (xs[i]+ds[i] <= xs[ind]):
            break
        o, ind = _sub(ind)
        res *= o
        res %= M
        if ind>=n:
            break
    return res+1, ind
out = []
done = 0
while True:
    o, done = _sub(done)
    out.append(o)
    if done>=n:
        break
result = 1
for o in out:
    result *= o
    result %= M
print(result)

Solution (Python):

import numpy as np

M = 998244353

n = int(input())
xs = [0] * n
ds = [0] * n
for i in range(n):
    x, d = (int(c) for c in input().split())
    ds[i] = d
    xs[i] = x
xs = np.array(xs)
ds = np.array(ds)

import sys
sys.setrecursionlimit(max(1000,n))

index = xs.argsort()
xs = xs[index]
ds = ds[index]

def _sub(i):
    
    if i==n-1:
        return 2, n
    res = 1
    ind = i+1
    while True:
        if (xs[i]+ds[i] <= xs[ind]):
            break
        o, ind = _sub(ind)
        res *= o
        res %= M
        if ind>=n:
            break
    return res+1, ind
out = []
done = 0
while True:
    o, done = _sub(done)
    out.append(o)
    if done>=n:
        break
result = 1
for o in out:
    result *= o
    result %= M
print(result)

Solution (Python):

from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list(map(lambda x: int(x)-1, input().split()))
def II(): return int(input())
def IF(): return float(input())
def LS(): return list(map(list, input().split()))
def S(): return list(input().rstrip())
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]


mod = 998244353

inf = 1e10



def solve():


    def init_max(init_max_val):
        
        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

    n = II()
    
    ide_ele_max = -1

    
    num_max = 2**(n).bit_length()
    seg_max = [ide_ele_max]*2*num_max
    xd = LIR(n)
    xd.sort()
    x = [x for x, d in xd]
    dp = [[0] * 2 for i in range(n + 1)]
    On = 0
    Off = 1
    dp[-1][On] =  1
    for i in range(n - 1, -1, -1):
        dp[i][Off] = (dp[i + 1][On] + dp[i + 1][Off]) % mod
        j = bisect_right(x, x[i] + xd[i][1] - 1) - 1
        if j == i:
            dp[i][On] = (dp[i + 1][On] + dp[i + 1][Off]) % mod
            update_max(i, i)
        else:
            j = query_max(i, j + 1)
            dp[i][On] = dp[j][On]
            update_max(i, j)
        
    print(sum(dp[0]) % mod)
    return



if __name__ == '__main__':
    solve()

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


class SegmentTreeRMQ(object):  
    def __init__(self, size, value):
        self.len = 1 << size.bit_length()
        
        self.array = [value] * (2 * self.len)

    def update(self, i, x):
        i += self.len
        while i > 0:
            self.array[i] = max(self.array[i], x)
            i >>= 1
        

    def get(self, i):
        return self.array[i + self.len]

    def get_maximum(self, l, r):
        L = l+self.len
        R = r+self.len
        ANS = -1 << 30

        while L < R:
            if L & 1:
                ANS = max(ANS, self.array[L])
                L += 1

            if R & 1:
                R -= 1
                ANS = max(ANS, self.array[R])
            L >>= 1
            R >>= 1

        return ANS


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

xd_array = sorted(xd_array, key=lambda x: x[0])
x_array = [i[0] for i in xd_array]
d_array = [i[1] for i in xd_array]

mod = 998244353

tree = SegmentTreeRMQ(N, -1)
ans_array = [0] * (N+1)
ans_array[-1] = 1
for i in range(N-1, -1, -1):
    move = x_array[i] + d_array[i] - 0.1
    max_index = bisect.bisect_left(x_array, move)
    max_move = max(i, tree.get_maximum(i, max_index))
    tree.update(i, max_move)
    ans_array[i] = (ans_array[i+1] + ans_array[max_move + 1]) % mod

print(ans_array[0])

Solution (Python):
import sys
import math
from collections import defaultdict
from bisect import bisect_left, bisect_right

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

mod = 998244353

def I(): return int(input())
def LI(): return list(map(int, input().split()))
def LIR(row,col):
    if row <= 0:
        return [[] for _ in range(col)]
    elif col == 1:
        return [I() for _ in range(row)]
    else:
        read_all = [LI() for _ in range(row)]
        return map(list, zip(*read_all))



from operator import itemgetter

def index_sort(A):
    A_sort = sorted(enumerate(A),key=itemgetter(1))
    index = [a[0] for a in A_sort]
    sorted_A = [a[1] for a in A_sort]
    return index, sorted_A




class SegmentTree:
    def __init__(self,N,default):
        
        self.op = max
        
        self.default = default
        self.N0 = 2**(N-1).bit_length()
        self.tree = [self.default]*(2*self.N0)
        
    
    def update(self,k,x):
        k += self.N0-1
        self.tree[k] = x
        while k >= 0:
            k = (k-1)//2
            self.tree[k] = self.op(self.tree[2*k+1], self.tree[2*k+2])

    
    def query(self,l,r):
        L = l+self.N0
        R = r+self.N0+1 
        s = self.default
        while L < R:
            if R & 1:
                R -= 1
                s = self.op(s,self.tree[R-1])
            if L & 1:
                s = self.op(s,self.tree[L-1])
                L += 1
            L >>= 1; R >>= 1
        return s

    
    def get(self,k):
        return self.tree[k+self.N0-1]

N = I()
X,D = LIR(N,2)

index,X = index_sort(X)
D = [D[i] for i in index]


end = SegmentTree(N,0)
for i in range(N):
    end.update(i,i)
for i in range(N-1)[::-1]:
    p = bisect_right(X,X[i]+D[i]-1)
    val = end.query(i,p-1)
    end.update(i,val)


dp = [0]*N
dp[N-1] = 2
for i in range(N-1)[::-1]:
    dp[i] = dp[i+1]
    if end.get(i) == N-1:
        dp[i] += 1
    else:
        dp[i] += dp[end.get(i)+1]
    dp[i] %= mod

print(dp[0])

Solution (Python):
N=int(input());R,d,f,s,x=sorted(list(map(int,input().split()))for i in range(N))+[(2e9,0)],[0]*N+[1],[0]*N,1,N
for i in range(N-1,-1,-1):
	while R[x][0]<sum(R[i]):x=f[x]
	d[i]=s=(s+d[x])%998244353;f[i],x=x,i
print(s)

Solution (Python):
N=int(input());R,d,f,s,x=sorted(list(map(int,input().split()))for i in range(N))+[(2e9,0)],[0]*N+[1],[0]*N,1,N
for i in range(N-1,-1,-1):
	while R[x][0]<sum(R[i]):x=f[x]
	d[i]=s=(s+d[x])%998244353;f[i],x=x,i
print(d[0])

Solution (Python):
N=int(input())
R,d,f,s,x=sorted(list(map(int,input().split()))for i in range(N))+[(2e9,0)],[0]*N+[1],[0]*N,1,N
for i in range(N-1,-1,-1):
	while R[x][0]<sum(R[i]):x=f[x]
	d[i]=s=(s+d[x])%998244353;f[i],x=x,i
print(d[0])

Solution (Python):
N=int(input())
R,d,f,s=sorted(list(map(int,input().split()))for i in range(N))+[(2e9,0)],[0]*N+[1],[0]*N,1
for i in range(N-1,-1,-1):
    x=i+1
    while x<N and R[x][0]<sum(R[i]):x=f[x]
    f[i]=x
    d[i]=s=(s+d[x])%998244353
print(d[0])

Solution (Python):
def i1():
 return int(input())
def i2():
 return [int(i) for i in input().split()]
import bisect
mod=998244353
n=int(input())
d=[]
N=1<<(n.bit_length())
t=[-1 for i in range(2*N-1)]

def ud(i,x):
  i+=N-1
  t[i]=x
  while i:
    i=(i-1)>>1
    if t[i*2+1]>t[i*2+2]:t[i]=t[i*2+1]
    else:t[i]=t[i*2+2]
     

def qr(a,b):
    a+=N-1
    b+=N-1
    L = -1
    R = -1
    while a < b:
      if a&1==0:
         if L<t[a]:L = t[a]
      if b&1==0:
         b-=1
         if R<t[b]:R = t[b]
      
      a>>=1
      b>>=1
      
         
    return max(L, R)
 
for i in range(n):
  d.append([int(i) for i in input().split()])
d.sort()
dx=[]
dd=[]
for i,j in d:
  dx.append(i)
  dd.append(j)
for i in range(n)[::-1]:
 tx=dx[i]+dd[i]
 j=bisect.bisect_left(dx,tx)
 tt=qr(i,j)
 if j-1>tt:ud(i,j-1)
 else:ud(i,tt)
dp=[0 for i in range(n+1)]
dp[-1]=1
for i in range(n)[::-1]:
  dp[i]+=dp[i+1]
  dp[i]%=mod
  dp[i]+=dp[t[i+N-1]+1]
  dp[i]%=mod
print(dp[0])

Solution (Python):
import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__

class RangeMinimumQuery:
    def __init__(self, n, F=min, e=float("inf"), fill=None):
        self.n0 = 2**(n-1).bit_length()
        self.F = F
        self.e = e
        if fill is None:
            fill = e
        self.data = [fill]*(2*self.n0)

    def construct(self, a):
        for i, x in enumerate(a):
            self.data[i+self.n0-1] = x
        for i in range(self.n0-2, -1, -1):
            self.data[i] = self.F(self.data[2*i+1], self.data[2*i+2])

    def query(self, l,r):
        l += self.n0
        r += self.n0
        res = self.e
        while l < r:
            if r&1:
                r -= 1
                res = self.F(res, self.data[r-1])
            if l&1:
                res = self.F(res, self.data[l-1])
                l += 1
            l >>=1
            r >>=1
        return res

    def update(self, i, x):
        i += self.n0-1
        self.data[i] = x
        while i:
            i = ~-i//2
            self.data[i] = self.F(self.data[2*i+1], self.data[2*i+2])


from bisect import bisect_left

mod = 998244353

n = int(input())
xd = [list(map(int, input().split())) for i in range(n)]
xd.sort()
xs = [i for i,j in xd]

RMQ = RangeMinimumQuery(n, max,0,0)
RMQ.construct(list(range(n)))

for i in reversed(range(n)):
    r = sum(xd[i])
    j = bisect_left(xs, r)
    k = RMQ.query(i, j)
    RMQ.update(i, k)

DP = [0]*(n+1)
DP[-1] = 1
for i in reversed(range(n)):
    j = RMQ.query(i, i+1)
    DP[i] = DP[i+1]+DP[j+1]
    DP[i] %= mod
print(DP[0])

Solution (Python):
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,l,r):
    l+=self.offset
    r+=self.offset
    ret=self.init
    while l<=r:
      ret=max(ret,self.tree[r])
      r=(r-1)//2
      ret=max(ret,self.tree[l])
      l=(l+1)//2
    return ret

mod=998244353
n=int(input())
arr=[list(map(int,input().split())) for _ in range(n)]
arr=sorted(arr,key=lambda x:x[0])
st=SegmentTreeMax(n,0)
ranges=[]
for i in range(n):
  x=arr[i][0]+arr[i][1]
  l=-1
  r=n
  while r-l!=1:
    mid=(l+r)//2
    if arr[mid][0]>=x:
      r=mid
    else:
      l=mid
  ranges.append(r-1)
  st.update(i,r-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):
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,l,r):
    l+=self.offset
    r+=self.offset
    ret=self.init
    while l<=r:
      ret=max(ret,self.tree[r])
      r=(r-1)//2
      ret=max(ret,self.tree[l])
      l=(l+1)//2
    return ret

mod=998244353
n=int(input())
arr=[list(map(int,input().split())) for _ in range(n)]
arr=sorted(arr,key=lambda x:x[0])
st=SegmentTreeMax(n,0)
ranges=[]
for i in range(n):
  x=arr[i][0]+arr[i][1]
  l=-1
  r=n
  while r-l!=1:
    mid=(l+r)//2
    if arr[mid][0]>=x:
      r=mid
    else:
      l=mid
  ranges.append(l)
  st.update(i,r)
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]
  dp[i]=dp[i+1]+dp[j]
  dp[i]%=mod
print(dp[0])

Solution (Python):
import sys
from bisect import bisect, bisect_left

class SquareDiv(): 
    def __init__(self, N, V):
        k = 1
        while k ** 2 < N: k += 1
        self.array = [V] * k
        self.size = k
        self.indivisual = [V] * N

    def update(self, i, v): 
        self.indivisual[i] = v
        self.array[i // self.size] = max(self.array[i // self.size], v)

    def search(self, left, right): 
        lk, rk = left // self.size, right // self.size
        if lk == rk:
            maxN = 0
            for i in range(left, right + 1): maxN = max(maxN, self.indivisual[i])
            return maxN
        else:
            maxN = self.search(left, (lk + 1) * self.size - 1)
            for k in range(lk + 1, rk): maxN = max(maxN, self.array[k])
            maxN = max(maxN, self.search(rk * self.size, right))
            return maxN

def solve():
    input = sys.stdin.readline
    N = int(input())
    R = [[int(i) for i in input().split()] for _ in range(N)]
    R.sort()
    mod = 998244353
    X = [R[i][0] for i in range(N)]
    Connect = SquareDiv(N, 0)
    DP = dict()
    DP[N] = 1
    for i in reversed(range(N)):
        right = max(i, Connect.search(i, bisect_left(X, sum(R[i])) - 1))
        Connect.update(i, right)
        DP[i] = (DP[right + 1] + DP[i + 1]) % mod
    print(DP[0])
    

    return 0

if __name__ == "__main__":
    solve()

Solution (Python):


def bisect(pos):
  l=-1
  r=n
  while r-l!=1:
    mid=(l+r)//2
    if arr[mid][0]>=pos:
      r=mid
    else:
      l=mid
  return r

mod=998244353
n=int(input())
arr=[list(map(int,input().split())) for _ in range(n)]
arr=sorted(arr,key=lambda x:x[0])
poss=[]
for i in range(n):
  poss.append(bisect(arr[i][0]+arr[i][1]))
poss.append(n)

offset=2**((n-1).bit_length())
st=[0]*(2*offset)

def update(pos,x):
  pos+=offset
  st[pos]=x
  while pos>1:
    y=st[pos^1]
    if x<=y:
      break
    pos>>=1
    st[pos]=x

def get_max(l,r):
  ret=0
  l+=offset
  r+=offset
  while l<r:
    if r&1:
      ret=max(ret,st[r-1])
    if l&1:
      ret=max(ret,st[l])
      l+=1
    l>>=1
    r>>=1
  return ret

for i in range(n):
  update(i,poss[i])
for i in range(n-1,-1,-1):
  poss[i]=get_max(i,poss[i])
  update(i,poss[i])

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

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

N = int(input())
XD = [[int(i) for i in input().split()] for _ in range(N)]

mod = 998244353

XD.sort()

class SegTree:
  def __init__(self, n, v, f) :
    i = 1
    while i < n : 
      i <<= 1
    self.n = i
    self.v = v
    self.f = f
    self.tree = [v] * (i << 1)

  def update(self, i, x) :
    i += self.n - 1
    self.tree[i] = x
    while i > 0 :
      i = (i - 1) // 2
      self.tree[i] = self.f(self.tree[i * 2 + 1], self.tree[i * 2 + 2])

  
  def query(self, l, r) :
    l = l + self.n
    r = r + self.n
    s = self.v
    while l < r :
      if r & 1 :
        r -= 1
        s = self.f(s, self.tree[r - 1])
      if l & 1 :
        s = self.f(s, self.tree[l - 1])
        l += 1
      l >>= 1
      r >>= 1
    return s

INF = 1 << 60
ST = SegTree(N, -INF, max)

xs = [x for x, _ in XD]
for i in range(N - 1, -1, -1) :
  x, d = XD[i]
  j = bisect_left(xs, x + d)
  ST.update(i, max(i, ST.query(i, j)))

dp = [0] * (N + 1)
dp[N] = 1

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

print(dp[N-1])

Solution (Python):
import sys
from operator import itemgetter

n, *xd = map(int, sys.stdin.buffer.read().split())
MOD = 998244353
xd = sorted(zip(xd[0::2], xd[1::2]))
xxx = list(map(itemgetter(0), xd)) + [10 ** 10]
ans = [0] * n + [1]
stack = [n]

for i in range(n - 1, -1, -1):
    x, d = xd[i]
    r = x + d
    while r > xxx[stack[-1]]:
        stack.pop()
    ans[i] = (ans[i + 1] + ans[stack[-1]]) % MOD
    stack.append(i)
print(ans[0])

Solution (Python):

N = int(input())
XD = []
for _ in range(N):
    x, d = map(int, input().split())
    XD.append((x, x+d))

MOD = 998244353


XD.sort(reverse=True)

sei = [(10**9, 0)]
pattern = [0]*(N+1)
pattern[0] = 1
for i, (s, e) in enumerate(XD):
    ei = i
    while e > sei[-1][0]:
        _, ei = sei.pop()
    sei.append((s, ei))
    pattern[i+1] = (pattern[i] + pattern[ei]) % MOD


print(pattern[-1])

Solution (Python):
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,copy,functools
import time,random

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**10
mod = 10**9+7
mod2 = 998244353
dd = [(-1,0),(0,1),(1,0),(0,-1)]
ddn = [(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(): return [list(map(int, l.split())) for l in sys.stdin.readlines()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()
def pf(s): return print(s, flush=True)
def pe(s): return print(str(s), file=sys.stderr)
def JA(a, sep): return sep.join(map(str, a))
def JAA(a, s, t): return s.join(t.join(map(str, b)) for b in a)


class Seg():
    def __init__(self, na, default, func):
        if isinstance(na, list):
            n = len(na)
        else:
            n = na
        i = 1
        while 2**i <= n:
            i += 1
        self.D = default
        self.H = i
        self.N = 2**i
        if isinstance(na, list):
            self.A = [default] * (self.N) + na + [default] * (self.N-n)
            for i in range(self.N-1,0,-1):
                self.A[i] = func(self.A[i*2], self.A[i*2+1])
        else:
            self.A = [default] * (self.N*2)
        self.F = func

    def find(self, i):
        return self.A[i + self.N]

    def update(self, i, x):
        i += self.N
        self.A[i] = x
        while i > 1:
            i = i // 2
            self.A[i] = self.merge(self.A[i*2], self.A[i*2+1])

    def merge(self, a, b):
        return self.F(a, b)

    def total(self):
        return self.A[1]

    def query(self, a, b):
        A = self.A
        l = a + self.N
        r = b + self.N
        res = self.D
        while l < r:
            if l % 2 == 1:
                res = self.merge(res, A[l])
                l += 1
            if r % 2 == 1:
                r -= 1
                res = self.merge(res, A[r])
            l >>= 1
            r >>= 1

        return res

def main():
    n = I()
    xd = sorted([LI() for _ in range(n)])
    xa = [x for x,_ in xd] + [inf]
    r = [0] * n + [1]
    def f(a,b):
        if a > b:
            return a
        return b
    seg = Seg(n+1,0,f)
    for i in range(n-1,-1,-1):
        x,d = xd[i]
        xi = bisect.bisect_left(xa, x+d)
        qi = seg.query(i,xi)
        if qi > xi:
            xi = qi
        seg.update(i,xi)
        r[i] = (r[i+1] + r[xi]) % mod2

    return r[0]


print(main())

Solution (Python):
mod = 998244353

N, *XD = map(int, open(0).read().split())

XD = sorted(zip(*[iter(XD)] * 2), reverse=True)

S = [(1e10, 0)]
dp = [1] + [0] * N
for i, (x, d) in enumerate(XD):
    j = i
    while S[-1][0] < x + d:
        _, j = S.pop()
    S.append((x, j))
    dp[i + 1] = (dp[i] + dp[j]) % mod

print(dp[-1])