Problem:


Score : 100 points

Problem Statement

You are given an array a_0, a_1, ..., a_{N-1} of length N. Process Q queries of the following types.

The type of i-th query is represented by T_i.

T_i=1: You are given two integers X_i,V_i. Replace the value of A_{X_i} with V_i.

T_i=2: You are given two integers L_i,R_i. Calculate the maximum value among A_{L_i},A_{L_i+1},\cdots,A_{R_i}.

T_i=3: You are given two integers X_i,V_i. Calculate the minimum j such that X_i \leq j \leq N, V_i \leq A_j. If there is no such j, answer j=N+1 instead.

Constraints

1 \leq N \leq 2 \times 10^5

0 \leq A_i \leq 10^9

1 \leq Q \leq 2 \times 10^5

1 \leq T_i \leq 3

1 \leq X_i \leq N, 0 \leq V_i \leq 10^9 (T_i=1,3)

1 \leq L_i \leq R_i \leq N (T_i=2)

All values in Input are integer.

Input

Input is given from Standard Input in the following format:

N Q
A_1 A_2 \cdots A_N
First query
Second query
\vdots
Q-th query

Each query is given in the following format:

If T_i=1,3,

T_i X_i V_i

If T_i=2,

T_i L_i R_i

Output

For each query with T_i=2, 3, print the answer.

Sample Input 1

5 5
1 2 3 2 1
2 1 5
3 2 3
1 3 1
2 2 4
3 1 3

Sample Output 1

3
3
2
6

First query: Print 3, which is the maximum of (A_1,A_2,A_3,A_4,A_5)=(1,2,3,2,1).

Second query: Since 3>A_2, j=2 does not satisfy the condition．Since 3 \leq A_3, print j=3.

Third query: Replace the value of A_3 with 1. It becomes A=(1,2,1,2,1).

Fourth query: Print 2, which is the maximum of (A_2,A_3,A_4)=(2,1,2).

Fifth query: Since there is no j that satisfies the condition, print j=N+1=6.



Sample input:
5 5
1 2 3 2 1
2 1 5
3 2 3
1 3 1
2 2 4
3 1 3


Sample output:
3
3
2
6

Submission status: Runtime Error

Solution code:
class Segment_Tree():
    def __init__(self,N,calc,unit,L=[]):
        """calcを演算とするN項のSegment Treeを作成

        N:要素数
        calc:演算(2変数関数,モノイド)
        unit:モノイドcalcの単位元 (xe=ex=xを満たすe)
        """
        self.calc=calc
        self.unit=unit

        N=max(N,len(L))

        d=max(1,(N-1).bit_length())
        k=2**d

        X=[unit]*(k-1)+L+[unit]*(k-len(L))

        self.num=k
        self.depth=d

        for i in range(k-2,-1,-1):
            X[i]=calc(X[2*i+1],X[2*i+2])

        self.data=X

    def index(self,k,index=0):
        return self.data[(self.num-1)+(k-index)]

    def update(self,k,x,index=0):
        """第k要素をxに変え,更新を行う.

        k:数列の要素
        x:更新後の値
        """

        m=(self.num-1)+(k-index)
        self.data[m]=x

        for _ in range(self.depth):
            m=(m-1)//2
            self.data[m]=self.calc(self.data[2*m+1],self.data[2*m+2])


    def sub_array(self,From,To,index=0,left_closed=True,right_closed=True):
        A=From-index+(not left_closed)
        B=To-index-(not right_closed)

        return self.__sub_array_second(A,B+1,0,0,self.num)

    def __sub_array_second(self,a,b,k,l,r):
        if r<=a or b<=l:
            return self.unit
        elif a<=l and r<=b:
            return self.data[k]
        else:
            alpha=self.__sub_array_second(a,b,2*k+1,l,(l+r)//2)
            beta=self.__sub_array_second(a,b,2*k+2,(l+r)//2,r)
            return self.calc(alpha,beta)

    def all_prod(self):
        return self.data[0]

    def max_right(self,l,r,cond,index=0):
        """以下の2つをともに満たすxの1つを返す.\n
        (1) r=l or cond(data[l]*data[l+1]*...*d[r-1]):True
        (2) r=x or cond(data[l]*data[l+1]*...*data[r]):False
        ※fが単調減少の時,cond(data[l]*...*data[r-1])を満たす最大のrとなる.

        cond:関数(引数が同じならば結果も同じ)
        cond(unit):True
        0<=l<=r<=n
        """
        l-=index
        assert 0<=l<=r<=self.num,"添字が範囲外"
        assert cond(self.unit),"単位元が条件を満たさない."

        if l==r:
            return r+index

        l+=(self.num-1)
        sm=self.unit

        calc=self.calc
        while True:
            while l%2:
                l=(l-1)>>1

            if not cond(calc(sm,self.data[l])):
                while l<self.num-1:
                    l=2*l+1

                    if cond(calc(sm,self.data[l])):
                        sm=calc(sm,self.data[l])
                        l+=1

                return min(l-(self.num-1)+index,r)

            sm=calc(sm,self.data[l])
            l+=1

            m=l+1
            if not (m&(-m) !=m):
                break

        return r+index
#================================================
N,Q=map(int,input().split())
A=list(map(int,input().split()))

S=Segment_Tree(N,lambda x,y:max(x,y),0,A)

X=[]
for _ in range(Q):
    T,alpha,beta=map(int,input().split())

    if T==1:
        S.update(alpha,beta,1)
    elif T==2:
        X.append(S.sub_array(alpha,beta,1))
    else:
        X.append(S.max_right(alpha,N,lambda x:x<beta,1))

print("\n".join(map(str,X)))

Submission status: Runtime Error

Solution code:
# Date [ 2020-09-08 00:35:49 ]
# Problem [ j.py ]
# Author Koki_tkg

import sys
# import math
# import bisect
# import numpy as np
# from decimal import Decimal
# from numba import njit, i8, u1, b1 #JIT compiler
# from itertools import combinations, product
# from collections import Counter, deque, defaultdict

# sys.setrecursionlimit(10 ** 6)
MOD = 10 ** 9 + 7
INF = 10 ** 9
PI = 3.14159265358979323846

def read_str():      return sys.stdin.readline().strip()
def read_int():      return int(sys.stdin.readline().strip())
def read_ints():     return map(int, sys.stdin.readline().strip().split())
def read_ints2(x):   return map(lambda num: int(num) - x, sys.stdin.readline().strip().split())
def read_str_list(): return list(sys.stdin.readline().strip().split())
def read_int_list(): return list(map(int, sys.stdin.readline().strip().split()))
def GCD(a: int, b: int) -> int: return b if a%b==0 else GCD(b, a%b)
def LCM(a: int, b: int) -> int: return (a * b) // GCD(a, b)

class SegmentTree:
    def __init__(self, array, function, identify):
        self.length = len(array)
        self.func, self.ide_ele = function, identify

        self.size = 1 << (self.length-1).bit_length()
        self.data = [self.ide_ele] * 2*self.size
        # set
        for i in range(self.length):
            self.data[self.size + i] = array[i]
        # build
        for i in range(self.size-1, 0, -1):
            self.data[i] = self.func(self.data[2*i], self.data[2*i + 1])

    def update(self, idx, x):
        idx += self.size
        self.data[idx] = x
        while idx > 0:
            idx >>= 1
            self.data[idx] = self.func(self.data[2*idx], self.data[2*idx + 1])
 
    def query(self, l, r):
        l += self.size; r += self.size+1
        l_ret = r_ret = self.ide_ele
        while l < r:
            if l & 1:
                l_ret = self.func(l_ret, self.data[l])
                l += 1
            if r & 1:
                r -= 1
                r_ret = self.func(self.data[r], r_ret)
            l >>= 1; r >>= 1
        return self.func(l_ret, r_ret)

    def get(self, idx):
        return self.data[idx+self.size]

def Main():
    n, q = read_ints()
    a = read_int_list()
    seg = SegmentTree(a, max, -float('inf'))
    for _ in range(q):
        t, x, v = read_ints()
        if t == 1:
            seg.update(~-x, v)
        elif t == 2:
            print(seg.query(~-x, v))
        else:
            l = x - 1; r = n + 1
            while r - l > 1:
                mid = (l + r) // 2
                if seg.query(~-x, ~-mid) >= v:
                    r = mid
                else:
                    l = mid
            print(r)

if __name__ == '__main__':
    Main()

Submission status: Runtime Error

Solution code:
# Date [ 2020-09-08 00:35:49 ]
# Problem [ j.py ]
# Author Koki_tkg

import sys
# import math
# import bisect
# import numpy as np
# from decimal import Decimal
# from numba import njit, i8, u1, b1 #JIT compiler
# from itertools import combinations, product
# from collections import Counter, deque, defaultdict

# sys.setrecursionlimit(10 ** 6)
MOD = 10 ** 9 + 7
INF = 10 ** 9
PI = 3.14159265358979323846

def read_str():      return sys.stdin.readline().strip()
def read_int():      return int(sys.stdin.readline().strip())
def read_ints():     return map(int, sys.stdin.readline().strip().split())
def read_ints2(x):   return map(lambda num: int(num) - x, sys.stdin.readline().strip().split())
def read_str_list(): return list(sys.stdin.readline().strip().split())
def read_int_list(): return list(map(int, sys.stdin.readline().strip().split()))
def GCD(a: int, b: int) -> int: return b if a%b==0 else GCD(b, a%b)
def LCM(a: int, b: int) -> int: return (a * b) // GCD(a, b)

class SegmentTree:
    def __init__(self, array, function, identify):
        self.length = len(array)
        self.func, self.ide_ele = function, identify

        self.size = 1 << (self.length-1).bit_length()
        self.data = [self.ide_ele] * 2*self.size
        # set
        for i in range(self.length):
            self.data[self.size + i] = array[i]
        # build
        for i in range(self.size-1, 0, -1):
            self.data[i] = self.func(self.data[2*i], self.data[2*i + 1])

    def update(self, idx, x):
        idx += self.size
        self.data[idx] = x
        while idx > 0:
            idx >>= 1
            self.data[idx] = self.func(self.data[2*idx], self.data[2*idx + 1])
 
    def query(self, l, r):
        l += self.size; r += self.size+1
        l_ret = r_ret = self.ide_ele
        while l < r:
            if l & 1:
                l_ret = self.func(l_ret, self.data[l])
                l += 1
            if r & 1:
                r -= 1
                r_ret = self.func(self.data[r], r_ret)
            l >>= 1; r >>= 1
        return self.func(l_ret, r_ret)

    def get(self, idx):
        return self.data[idx+self.size]

def Main():
    n, q = read_ints()
    a = read_int_list()
    seg = SegmentTree(a, max, -float('inf'))
    for _ in range(q):
        t, x, v = read_ints()
        if t == 1:
            seg.update(~-x, v)
        elif t == 2:
            print(seg.query(x, v))
        else:
            l = x; r = n + 1
            while r - l > 1:
                mid = (l + r) // 2
                if seg.query(x, mid) >= v:
                    r = mid
                else:
                    l = mid
            print(r)

if __name__ == '__main__':
    Main()