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
input = sys.stdin.readline

class SegmentTree(object):
 
    def __init__(self, init_array, seg_func=min, seg_func_null=10 ** 9 + 7):
 
        self.seg_func = seg_func
        self.seg_func_null = seg_func_null
        self.n = 1
        while self.n < len(init_array):
            self.n *= 2
        self.dat = [0] * (2 * self.n - 1)
        for i in range(len(init_array)):
            self.dat[self.n - 1 + i] = init_array[i]
        for i in range(self.n - 2, -1, -1):
            self.dat[i] = self.seg_func(self.dat[2 * i + 1], self.dat[2 * i + 2])
 
    def update(self, k, a):
        k += self.n - 1
        self.dat[k] = a
        while k > 0:
            k = (k - 1) // 2
            self.dat[k] = self.seg_func(self.dat[k * 2 + 1], self.dat[k * 2 + 2])
 
    def query(self, p, q):
        
        if q <= p:
            return self.seg_func_null
 
        p += self.n - 1
        q += self.n - 2
        res = self.seg_func_null
 
        while q - p > 1:
            if p & 1 == 0:
                res = self.seg_func(res, self.dat[p])
            if q & 1 == 1:
                res = self.seg_func(res, self.dat[q])
                q -= 1
            p = p // 2
            q = (q-1) // 2
        if p == q:
            res = self.seg_func(res, self.dat[p])
        else:
            res = self.seg_func(self.seg_func(res, self.dat[p]), self.dat[q])
 
        return res
 
N = int(input())
X = [0]*N
D = [0]*N
XD = [None]*N
for i in range(N):
    X, D = (int(i) for i in input().split())
    XD[i] = (X, D)
XD.sort()

import bisect
seg = SegmentTree(list(range(N)), max, -1)
L = list(range(N))

for i in range(N)[::-1]:
    x, d = XD[i]
    b = bisect.bisect_left(XD, (x+d-0.5, d))-1
    m = seg.query(i,b+1)
    seg.update(i,m)
    L[i] = m

ans = [0]*N
res = 1
for i in range(N)[::-1]:
    if L[i] == i:
        ans[i] = res
        res *= 2
    else:
        ans[i] = ans[L[i]]
        res += ans[i]
    res %= 998244353
print(res)

Solution (Python):
from bisect import bisect_left


LARGE = 998244353


class SegmentTree(object):

    def __init__(self, init_array, seg_func=min, seg_func_null=10 ** 9 + 7):

        self.seg_func = seg_func
        self.seg_func_null = seg_func_null
        self.n = 1
        while self.n < len(init_array):
            self.n *= 2
        self.dat = [0] * (2 * self.n - 1)
        for i in range(len(init_array)):
            self.dat[self.n - 1 + i] = init_array[i]
        for i in range(self.n - 2, -1, -1):
            self.dat[i] = self.seg_func(self.dat[2 * i + 1], self.dat[2 * i + 2])

    def update(self, k, a):
        k += self.n - 1
        self.dat[k] = a
        while k > 0:
            k = (k - 1) // 2
            self.dat[k] = self.seg_func(self.dat[k * 2 + 1], self.dat[k * 2 + 2])

    def query(self, p, q):
        
        if q <= p:
            return self.seg_func_null

        p += self.n - 1
        q += self.n - 2
        res = self.seg_func_null

        while q - p > 1:
            if p & 1 == 0:
                res = self.seg_func(res, self.dat[p])
            if q & 1 == 1:
                res = self.seg_func(res, self.dat[q])
                q -= 1
            p = p // 2
            q = (q-1) // 2
        if p == q:
            res = self.seg_func(res, self.dat[p])
        else:
            res = self.seg_func(self.seg_func(res, self.dat[p]), self.dat[q])

        return res


def solve(n, x_list, d_list):
    reach_right = [0] * n
    reach_right[-1] = n - 1
    
    seg = SegmentTree(list(range(n)), max, -1)
    for i in range(n - 2, -1, -1):
        j = bisect_left(x_list, x_list[i] + d_list[i])
        k = seg.query(i, j)
        seg.update(i, k)
        reach_right[i] = k
    
    dp = [[0] * 2 for _ in range(n)]
    dp[n - 1][0] = 1
    dp[n - 1][1] = 1
    for i in range(n - 2, -1, -1):
        dp[i][0] = (dp[i + 1][0] + dp[i + 1][1]) % LARGE
        j = reach_right[i] + 1
        if j <= n - 1:
            dp[i][1] = (dp[j][0] + dp[j][1]) % LARGE
        else:
            dp[i][1] = 1

    return (dp[0][0] + dp[0][1]) % LARGE


def main():
    n = int(input())
    xd_list = sorted([list(map(int, input().split())) for _ in range(n)], key=lambda x: x[0])
    x_list = [xd[0] for xd in xd_list]
    d_list = [xd[1] for xd in xd_list]
    res = solve(n, x_list, d_list)
    print(res)


def test():
    assert solve(2, [1, 3], [5, 3]) == 3
    assert solve(3, [-1, 3, 6], [10, 3, 5]) == 5
    assert solve(4, [-10, -4, 4, 7], [3, 3, 3, 10]) == 16


if __name__ == "__main__":
    test()
    main()

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

class SegmentTree():
    def __init__(self,param,default,func):
        if isinstance(param,list):
            n=len(param)
        else:
            n=param
        self.d=default
        self.leaf=1<<(n-1).bit_length()
        if isinstance(param,list):
            self.tree=[default]*(self.leaf-1)+param+[default]*(self.leaf-n)
            for i in range(self.leaf-2,-1,-1):
                self.tree[i]=func(self.tree[i*2+1],self.tree[i*2+2])
        else:
            self.tree=[default]*(self.leaf*2-1)
        self.f=func
    def find(self,i):
        return self.tree[i+self.leaf-1]
    def update(self,idx,a):
        idx+=self.leaf-1
        self.tree[idx]=a
        while idx:
            idx=(idx-1)>>1
            self.tree[idx]=self.merge(self.tree[idx*2+1],self.tree[idx*2+2])
    def merge(self,a,b):
        return self.f(a,b)
    def get_top(self):
        return self.tree[0]
    def query(self,a,b): 
        T=self.tree
        l,r=a+self.leaf-1,b+self.leaf-1
        res=self.d
        while l<r:
            if not l%2:
                res=self.merge(res,T[l])
                l+=1
            if not r%2:
                r-=1
                res=self.merge(res,T[r])
            l>>=1; r>>=1
        return res

def main():
    mod=998244353
    n=int(input())
    XD=[list(map(int,input().split())) for _ in range(n)]
    XD.sort()
    X=[x for x,d in XD]
    seg=SegmentTree(n,-1,max)
    DP=[0]*(n+1)
    DP[-1]=1
    for i in reversed(range(n)):
        x,d=XD[i]
        j=bisect_left(X,x+d)
        r=max(i,seg.query(i+1,j))
        seg.update(i,r)
        DP[i]=(DP[i+1]+DP[r+1])%mod
    print(DP[0])
    
if __name__=='__main__':
    main()

Solution (Python):
class SegTree:
    def __init__(self, init_val, ide_ele, segfunc):
        self.n = len(init_val)
        self.num =2**(self.n-1).bit_length()
        self.ide_ele = ide_ele
        self.seg = [self.ide_ele]*2*self.num
        self.segfunc = segfunc
        
        
        for i in range(self.n):
            self.seg[i+self.num-1] = init_val[i]    
        
        for i in range(self.num-2,-1,-1) :
            self.seg[i] = 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
    


import sys
input = sys.stdin.readline
N = int(input())


GOTO = [i for i in range(1,N+1)]
INF = 10**15
ide_ele = -1
SEG = SegTree(GOTO,ide_ele,max)


LIST = []
XX = []
mod = 998244353

for i in range(N):
    X,D = map(int,input().split())
    LIST.append([X,D])

LIST.sort(key=lambda x: x[0])
for i in range(N):
    XX.append(LIST[i][0])


import bisect
for i in range(N-1):
    j = N-2-i
    Xj = LIST[j][0]
    Dj = LIST[j][1]
    Nj = bisect.bisect_right(XX, Xj+Dj-1)
    
    NEXT = SEG.query(j+1,Nj)
    if NEXT != -1:
        GOTO[j] = NEXT
        SEG.update(j,NEXT)
    
S = [-1]*(N+1)
S[N] = 1



for i in range(N):
    j = N-1-i
    S[j] = S[j+1] + S[GOTO[j]]
    S[j] %= mod

print(S[0])

Solution (Python):
from bisect import bisect
from itertools import accumulate
from functools import reduce
from sys import setrecursionlimit

setrecursionlimit(10000000)

MOD = 998244353

def solve(robots):
    N = len(robots)+1
    robots.sort()

    parent = [None]*N

    stack = [(float('inf'),0)]
    for i,(x,d) in enumerate(robots,start=1):
        d += x
        while stack[-1][0] <= x:
            stack.pop()
        parent[i] = stack[-1][1]
        while stack[-1][0] <= d:
            stack.pop()
        stack.append((d,i))

    dp = [1]*N
    for i in reversed(range(1,N)):
        p = parent[i]
        dp[p] *= dp[i]+1
        dp[p] %= MOD
    return dp[0]

if __name__ == '__main__':
    N = int(input())
    robots = [tuple(map(int,input().split())) for _ in range(N)]
    print(solve(robots))

Solution (Python):
class SegTree:
    def __init__(self, init_val, ide_ele, segfunc):
        self.n = len(init_val)
        self.num =2**(self.n-1).bit_length()
        self.ide_ele = ide_ele
        self.seg = [self.ide_ele]*2*self.num
        self.segfunc = segfunc
        
        
        for i in range(self.n):
            self.seg[i+self.num-1] = init_val[i]    
        
        for i in range(self.num-2,-1,-1) :
            self.seg[i] = 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
    

N = int(input())


GOTO = [i for i in range(1,N+1)]
INF = 10**15
ide_ele = -1
SEG = SegTree(GOTO,ide_ele,max)


LIST = []
XX = []
mod = 998244353

for i in range(N):
    X,D = map(int,input().split())
    LIST.append([X,D])

LIST.sort(key=lambda x: x[0])
for i in range(N):
    XX.append(LIST[i][0])


import bisect
for i in range(N-1):
    j = N-2-i
    Xj = LIST[j][0]
    Dj = LIST[j][1]
    Nj = bisect.bisect_right(XX, Xj+Dj-1)
    
    NEXT = SEG.query(j+1,Nj)
    if NEXT != -1:
        GOTO[j] = NEXT
        SEG.update(j,NEXT)
    
S = [-1]*(N+1)
S[N] = 1



for i in range(N):
    j = N-1-i
    S[j] = S[j+1] + S[GOTO[j]]
    S[j] %= mod

print(S[0])

Solution (Python):
from bisect import bisect
from itertools import accumulate
from functools import reduce
from sys import setrecursionlimit

setrecursionlimit(10000000)

MOD = 998244353

def solve(robots):
    N = len(robots)
    robots.sort()

    parent = [None]*(N+1)

    stack = [(float('inf'),0)]
    for i,(x,d) in enumerate(robots,start=1):
        d += x
        while stack[-1][0] <= x:
            stack.pop()
        parent[i] = stack[-1][1]
        while stack[-1][0] <= d:
            stack.pop()
        stack.append((d,i))

    dp = [1]*(N+1)
    for i in reversed(range(1,N+1)):
        p = parent[i]
        dp[p] *= dp[i]+1
        dp[p] %= MOD
    return dp[0]

if __name__ == '__main__':
    N = int(input())
    robots = [tuple(map(int,input().split())) for _ in range(N)]
    print(solve(robots))

Solution (Python):
class SegTree:
    def __init__(self, init_val, ide_ele, segfunc):
        self.n = len(init_val)
        self.num =2**(self.n-1).bit_length()
        self.ide_ele = ide_ele
        self.seg = [self.ide_ele]*2*self.num
        self.segfunc = segfunc
        
        
        for i in range(self.n):
            self.seg[i+self.num-1] = init_val[i]    
        
        for i in range(self.num-2,-1,-1) :
            self.seg[i] = 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
    

N = int(input())


A = [i for i in range(1,N+1)]
INF = 10**15
ide_ele = -1
SEG = SegTree(A,ide_ele,max)


LIST = []
XX = []
mod = 998244353

for i in range(N):
    X,D = map(int,input().split())
    XX.append(X)
    LIST.append([X,D])

XX.sort()
LIST.sort(key=lambda x: x[0])

GOTO = [i for i in range(1,N+1)]

import bisect
for i in range(N-1):
    j = N-2-i
    Xj = LIST[j][0]
    Dj = LIST[j][1]
    Nj = bisect.bisect_right(XX, Xj+Dj-1)
    
    NEXT = SEG.query(j+1,Nj)
    if NEXT != -1:
        GOTO[j] = NEXT
        SEG.update(j,NEXT)
    
S = [-1]*(N+1)
S[N] = 1



for i in range(N):
    j = N-1-i
    S[j] = S[j+1] + S[GOTO[j]]
    S[j] %= mod

print(S[0])

Solution (Python):
import sys
range = xrange
input = raw_input

class segtree:
    def __init__(self,data):
        n = len(data)
        m = 1
        while m < n:
            m *= 2
        self.m = m
        self.data = [0]*(m + m)
        self.data[m: m + n] = data
        for i in reversed(range(1, m)):
            self.data[i] = max(self.data[2*i], self.data[2*i + 1])

    def setter(self, i, val):
        i += self.m
        while i:
            self.data[i] = val
            val = max(val, self.data[i ^ 1])
            i >>= 1

    def maxer(self, l, r):
        l += self.m
        r += self.m
        maxi = 0
        while l < r:
            if l & 1:
                maxi = max(maxi, self.data[l])
                l -= 1
            if r & 1:
                r -= 1
                maxi = max(maxi, self.data[r])
            l >>= 1
            r >>= 1
        return maxi

inp = [int(x) for x in sys.stdin.read().split()]
ii = 0

n = inp[ii]; ii += 1

X = inp[ii + 0: ii + 2 * n: 2]
D = inp[ii + 1: ii + 2 * n: 2]

order = sorted(range(n), key = X.__getitem__)

X = [X[i] for i in order]
D = [D[i] for i in order]

MOD = 998244353
ways = [0]*(n + 1)
ways[-1] = 1

seg = segtree(list(range(n)))
for i in reversed(range(n)):
    a = i
    b = n - 1
    while a < b:
        c = a + b + 1 >> 1
        if X[c] < X[i] + D[i]:
            a = c
        else:
            b = c - 1
    reach = seg.maxer(i, a + 1)
    seg.setter(i, reach)

    ways[i] = (ways[i + 1] + ways[reach + 1]) % MOD

print ways[0]

Solution (Python):

class SegmentTree:
    def __init__(self, L, op, ide):
        self.op = op
        self.ide = ide
        self.sz = len(L)
        self.n = 1
        self.s = 1
        for i in range(1000):
            self.n *= 2
            self.s += 1
            if self.n >= self.sz:
                break
        self.node = [self.ide]*(2*self.n-1)

        
        

        
        
    
    def add(self, a, x):
        k = a+self.n-1
        self.node[k] += x
        for i in range(1000):
            k = (k-1)//2
            self.node[k] = self.op(self.node[2*k+1], self.node[2*k+2])
            if k <= 0:
                break
    
    def substitute(self, a, x):
        k = a+self.n-1
        self.node[k] = x
        for i in range(1000):
            k = (k-1)//2
            self.node[k] = self.op(self.node[2*k+1], self.node[2*k+2])
            if k <= 0:
                break

    def get_one(self, a):
        k = a+self.n-1
        return self.node[k]
    
    def get(self, l, r):
        res = self.ide
        n = self.n
        if self.sz <= r or 0 > l:
            print('ERROR: the indice are wrong.')
            return False

        for i in range(self.s):
            count = 2**i-1
            a = (r+1)//n
            b = (l-1)//n
            if a-b == 3:
                res = self.op(self.node[count+b+1],res)
                res = self.op(self.node[count+b+2],res)
                right = a*n
                left = (b+1)*n-1
                break
            if a-b == 2:
                res = self.op(self.node[count+b+1],res)
                right = a*n
                left = (b+1)*n-1
                break
            n = n//2

        
        n1 = n//2        
        for j in range(i+1,self.s):
            count = 2**j-1 
            a = (left+1)//n1
            b = (l-1)//n1
            if a-b == 2:
                res = self.op(self.node[count+b+1],res)
                left = (b+1)*n1-1                
            n1 = n1//2

        
        n1 = n//2        
        for j in range(i+1,self.s):
            count = 2**j-1 
            a = (r+1)//n1
            b = (right-1)//n1
            if a-b == 2:
                res = self.op(self.node[count+b+1],res)
                right = a*n1                
            n1 = n1//2
        return res
    
import sys
from operator import itemgetter
sys.setrecursionlimit(500000)
def input():
    return sys.stdin.readline()[:-1]

def main():
    N = int(input())
    def max_func(a,b):
        if a>b:
            return a
        else:
            return b
    ST = SegmentTree([0]*N,max_func,0)

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

    M.sort(key=itemgetter(0))

    def bisect(l,v):
        r = N-1
        if M[r][0] < v:
            return r
        while r-l>1:
            if M[(r+l)//2][0]<v:
                l = (r+l)//2
            else:
                r = (r+l)//2
        return l


    for i in range(N):
        j = N-i-1
        index = bisect(j,M[j][0]+M[j][1])
        if N-index-1 < i:
            ST.substitute(j,ST.get(j,index))
        else:
            ST.substitute(j,j)
            

    DP = [0]*(N+1)
    DP[0] = 1
    mod = 998244353
    
    for i in range(N):
        
        index = ST.get_one(N-i-1)
        j = N-1-index
        DP[i+1] = (DP[j]+DP[i])%mod

    print(DP[N])

if __name__ == '__main__':
    main()

Solution (Python):
def main():
    from bisect import bisect_left

    import sys
    input = sys.stdin.readline
    N = int(input())

    MOD = 998244353

    X = []
    X_append = X.append
    dic = dict() 

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

    X.sort()
    lst = []
    lst_append = lst.append
    for x in X:
        tmp = bisect_left(X, dic[x])
        lst_append(tmp)

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

    dp[N][0] = 1
    dp[N][1] = 0

    class SegmentTree:
        __slots__ = ["_default_value", "_seg_func", "_modifying_func", "_size", "_tree"]

        def __init__(self, initial_values: "Sequence", default_value: "Union[int, str]", seg_func: "Callable",
                    modifying_func: "Optional[Callable]" = None) -> None:
            self._default_value = default_value
            self._seg_func = seg_func
            self._modifying_func = modifying_func
            self._size = 1 << (len(initial_values) - 1).bit_length()
            self._tree = self._build(initial_values)

        def _build(self, initial_values: "Sequence") -> "List":
            """Build a segment tree with initial values."""
            tree = [self._default_value] * (2 * self._size)

            if self._modifying_func:
                initial_values = map(self._modifying_func, initial_values)

            for idx, val in enumerate(initial_values):  
                tree[idx + self._size - 1] = val

            for idx in range(self._size - 2, -1, -1):  
                tree[idx] = self._seg_func(tree[2 * idx + 1], tree[2 * idx + 2])

            return tree

        def update(self, index: int, value: int) -> None:
            """Update index to value."""
            index += self._size - 1
            if self._modifying_func:
                value = self._modifying_func(value)
            self._tree[index] = value
            while index:
                index = (index - 1) // 2
                self._tree[index] = self._seg_func(self._tree[2 * index + 1], self._tree[2 * index + 2])

        def query(self, left: int, right: int) -> "Union[int, str]":
            """Respond to query in [left, right]."""
            left += self._size
            right += self._size
            result = self._default_value
            while left < right:
                if left & 1:
                    result = self._seg_func(result, self._tree[left - 1])
                    left += 1
                if right & 1:
                    right -= 1
                    result = self._seg_func(result, self._tree[right - 1])
                left >>= 1
                right >>= 1
            return result

    tree = SegmentTree(lst, 0, max, None)

    for i in range(N - 1, -1, -1):
        tmp = max(i + 1, tree.query(i, lst[i])) 
        
        dp[i][0] = (dp[i + 1][0] + dp[i + 1][1]) % MOD
        dp[i][1] = (dp[tmp][0] + dp[tmp][1]) % MOD
        tree.update(i, tmp)

    print ((dp[0][0] + dp[0][1]) % MOD)

    
    
    



if __name__ == '__main__':
    main()

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

N=int(input())
R=[tuple(map(int,input().split())) for i in range(N)]+[(1<<31,1<<31)]
R.sort(key=itemgetter(0))
RMAX=[x+y for x,y in R]

seg_el=1<<(N.bit_length())
SEG=[-1]*(2*seg_el)

def update(n,x,seg_el):
    i=n+seg_el
    SEG[i]=x
    i>>=1
    
    while i!=0:
        SEG[i]=max(SEG[i*2],SEG[i*2+1])
        i>>=1
        
def getvalues(l,r):
    L=l+seg_el
    R=r+seg_el
    ANS=-1<<30

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

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

    return ANS

for i in range(N-1,-1,-1):
    x=bisect.bisect_left(R,(RMAX[i],0))
    MAX=getvalues(i,x)
    if MAX==-1:
        update(i,x,seg_el)
    else:
        update(i,MAX,seg_el)

mod=998244353


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

for i in range(N):
    DP[i+1]=(DP[i]+DP[i+1])%mod
    DP[getvalues(i,i+1)]=(DP[i]+DP[getvalues(i,i+1)])%mod

    
print(DP[-1]%mod)

Solution (Python):
import sys
from bisect import bisect
def input():
	return sys.stdin.buffer.readline()[:-1]

MOD = 998244353
n = int(input())
r = []
for _ in range(n):
	x, d = map(int, input().split())
	r.append((-x, -x-d))
r.sort()

INF = 10**30

class Rmin():
	def __init__(self, size):
		
		self.n = 1
		while self.n < size:
			self.n *= 2
		self.node = [INF] * (2*self.n-1)

	def Access(self, x):
		return self.node[x+self.n-1]

	def Update(self, x, val):
		x += self.n-1
		self.node[x] = val
		while x > 0:
			x = (x-1)//2
			self.node[x] = min(self.node[2*x+1], self.node[2*x+2])
		return

	
	def Get(self, l, r):
		L, R = l+self.n, r+self.n
		s = INF
		while L<R:
			if R & 1:
				R -= 1
				s = min(s, self.node[R-1])
			if L & 1:
				s = min(s, self.node[L-1])
				L += 1
			L >>= 1
			R >>= 1
		return s

leftmost = Rmin(n)

wait = [r[0][0]]
dp = [[0 for _ in range(2)] for _ in range(n)]
dp[0] = [1, 1]
leftmost.Update(0, 0)

for i in range(1, n):
	dp[i][1] = (dp[i-1][0] + dp[i-1][1]) % MOD	
	if r[i][1] < wait[-1]:
		b = bisect(wait, r[i][1])
		mi = leftmost.Get(b, i)
		dp[i][0] = dp[mi][0]
		leftmost.Update(i, mi)
	else:
		dp[i][0] = dp[i][1]
		leftmost.Update(i, i)
	wait.append(r[i][0])

print((dp[n-1][0] + dp[n-1][1]) % MOD)

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 = 998244353
import operator
class SegmentTree:
    def __init__(self, size, default, f = operator.add):
        self.size = 2**(size-1).bit_length()
        self.default = default
        self.dat = [default]*(self.size*2)
        self.f = f

    def update(self, i, x):
        i += self.size
        self.dat[i] = x
        while i > 0:
            i >>= 1
            self.dat[i] = self.f(self.dat[i*2], self.dat[i*2+1])

    def add(self, i, x):
        i += self.size
        self.dat[i] = self.f(self.dat[i], x)
        while i > 0:
            i >>= 1
            self.dat[i] = self.f(self.dat[i], x)

    def get(self, a, b = None):
        if b is None:
            b = a + 1
        l, r = a + self.size, b + self.size
        lres, rres = self.default, self.default
        while l < r:
            if l & 1:
                lres = self.f(lres, self.dat[l])
                l += 1

            if r & 1:
                r -= 1
                rres = self.f(self.dat[r], rres)
            l >>= 1
            r >>= 1
        res = self.f(lres, rres)
        return res
def solve():
    n = I()
    a = LIR(n)
    a.sort()
    ans = [None]*(n+1)
    s = SegmentTree(n,0,max)
    ans[n] = 1
    X = [i[0] for i in a]
    for i in range(n)[::-1]:
        x,d = a[i]
        k = x+d
        j = bisect.bisect_left(X,k)
        b = s.get(i,j)
        if j < b:
            j = b
        s.update(i,j)
        ans[i] = ans[j]+ans[i+1]
        ans[i] %= mod
    print(ans[0])
    return


if __name__ == "__main__":
    solve()

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

    class SegTree():
        def __init__(self, N):
            
            self.N0 = 2 ** (N - 1).bit_length()
            self.INF = 2100000000
            self.seg_min = [-self.INF] * (2 * self.N0)

        def update(self, index, value):
            index += self.N0 - 1
            self.seg_min[index] = value
            while index > 0:
                index = (index - 1) >> 1
                L = self.seg_min[index * 2 + 1]
                R = self.seg_min[index * 2 + 2]
                if L > R:
                    self.seg_min[index] = L
                else:
                    self.seg_min[index] = R
                

        def query(self, first, last):
            first += self.N0 - 1
            last += self.N0 - 1
            ret = -self.INF
            while first <= last:
                if not first & 1:
                    ret_new = self.seg_min[first]
                    if ret_new > ret:
                        ret = ret_new
                    
                if last & 1:
                    ret_new = self.seg_min[last]
                    if ret_new > ret:
                        ret = ret_new
                    
                first = first >> 1
                last = (last >> 1) - 1
            return ret

    mod = 998244353
    N = int(input())
    info = []
    X = []
    for _ in range(N):
        x, d = map(int, input().split())
        info.append((x, x+d))
        X.append(x)
    info.sort(key=lambda p: p[0])
    X.sort()
    segtree = SegTree(N+1)
    for i in range(N):
        segtree.update(i+1, info[i][1])

    dp = [0] * (N+1)
    dp[-1] = 1
    for i in range(N-1, -1, -1):
        l, r = info[i]
        j = bisect_left(X, r)
        rmax = segtree.query(i+1, j)
        
        segtree.update(i+1, rmax)
        j2 = bisect_left(X, rmax)
        dp[i] = (dp[i+1] + dp[j2])%mod
    print(dp[0])
    


if __name__ == '__main__':
    main()