Problem:
 Score : 400 points    Problem Statement You are given a sequence A_1, A_2, ..., A_N and an integer K .  Print the maximum possible length of a sequence B that satisfies the following conditions:   B is a (not necessarily continuous) subsequence of A .  For each pair of adjacents elements of B , the absolute difference of the elements is at most K .       Constraints  1 \leq N \leq 300,000  0 \leq A_i \leq 300,000  0 \leq K \leq 300,000  All values in input are integers.         Input Input is given from Standard Input in the following format:  N  K  A_1  A_2  :  A_N       Output Print the answer.        Sample Input 1 10 3
1
5
4
3
8
6
9
7
2
4      Sample Output 1 7  For example, B = (1, 4, 3, 6, 9, 7, 4) satisfies the conditions.   It is a subsequence of A = (1, 5, 4, 3, 8, 6, 9, 7, 2, 4) .  All of the absolute differences between two adjacent elements ( |1-4|, |4-3|, |3-6|, |6-9|, |9-7|, |7-4| ) are at most K = 3 .

Solution (Python):

import sys
N,K=map(int, sys.stdin.readline().split())
A=[ int(sys.stdin.readline().strip()) for _ in range(N) ]
max_A=max(A)


N0 = 2**(max_A).bit_length()
data = [0]*(2*N0)

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

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

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

for i,a in enumerate(A):
    update(a,query(max(a-K,0),min(a+K+1,max_A+1))+1)

print query(0,max_A+1)

Solution (Python):

import sys
N,K=map(int, sys.stdin.readline().split())
A=[ int(sys.stdin.readline().strip()) for _ in range(N) ]
max_A=max(A)


N0 = 2**(max_A).bit_length()
data = [0]*(2*N0)

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

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

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

for i,a in enumerate(A):
    update(a,query(max(a-K,0),min(a+K+1,max_A+1))+1)

print query(0,max_A+1)

Solution (Python):

import sys
N,K=map(int, sys.stdin.readline().split())
A=[ int(sys.stdin.readline().strip()) for _ in range(N) ]
max_A=max(A)


N0 = 2**(3*10**5-1).bit_length()
data = [0]*(2*N0)

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

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

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

for i,a in enumerate(A):
    update(a,query(max(a-K,0),min(a+K+1,max_A+1))+1)

print query(0,max_A+1)

Solution (Python):
def op(a:int, b:int): return max(a, b)
class Segtree():
    def __init__(self, n, segfunc=max, init=0):
        self.n  = n
        self.segfunc = segfunc
        self.init = init
        self.num = 1 << (self.n-1).bit_length() 
        self.tree = [self.init]*2*self.num 


    def update(self, k, x):
        k += self.num
        self.tree[k] = x
        while k > 1:
            
            self.tree[k>>1] = self.segfunc(self.tree[k], self.tree[k^1])
            k>>=1

    def query(self, l, r):
        if r<=l: return self.init
        l += self.num
        r += self.num
        res = self.init
        while(r>l):
            if l&1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r&1:
                r -= 1
                res = self.segfunc(res, self.tree[r])
            l = l//2
            r = r//2
        return res

n, k = map(int, input().split())
max_a = 3*10**5+7
st = Segtree(max_a)
for i in range(n):
    a = int(input())
    temp = st.query(max(0, a-k), min(a+k+1, max_a+1))+1
    st.update(a, temp)

print(st.tree[1])

Solution (Python):

class segtree:
    """
    segment tree
    value store as object type and get update function(merge_func) from outside

    Attributes
    ----------
    n : int
        Number of elements
    initialize_func : func
        function for initialization
    merge_func : func
        function for merge x and y to x(this merge is distruction update)

    Methods
    -------
    update(i, x)
        update tree[i] value to x
    get(a, b)
        get value from [a, b)
        include a but not include b, return a merged value
    """
    def __init__(self, n, initialize_func, merge_func):
        """
        Constructer(Initialize parameter in this class)

        Parameters
        ----------
        n : int
            Number of elements
        initialize_func : func
            function for initialization
        merge_func : func
            function for merge x and y to x(this merge is distruction update)
        """
        self.n = n
        self.initialize = initialize_func
        self.merge = merge_func
        n2 = 1  
        while n2 < n:
            n2 <<= 1
        self.n2 = n2
        self.tree = [initialize_func() for _ in range(n2 << 1)]

    def update(self, index, x):
        index += self.n2
        self.tree[index] = self.merge(self.tree[index], x)
        while index > 1:
            
            x = self.merge(x, self.tree[index ^ 1])
            index >>= 1  
            self.tree[index] = self.merge(self.tree[index], x)

    def get(self, a, b):
        result = self.initialize()
        q = [(1, 0, self.n2)]
        while q:
            k, left, right = q.pop()
            if a <= left and right <= b:
                result = self.merge(result, self.tree[k])
                continue
            m = (left + right) // 2
            k <<= 1
            if a < m and left < b:
                q.append((k, left, m))
            if a < right and left < m:
                q.append((k + 1, m, right))
        return result


def main():
    N, K = map(int, input().split())
    A = [int(input()) for _ in range(N)]
    max_A = 3 * 10 ** 5 + 1

    seg = segtree(max_A, lambda: 0, max)
    for a in A:
        next = seg.get(max(0, a - K), min(a + K + 1, max_A))
        seg.update(a, next + 1)
    print(seg.get(0, max_A))


if __name__ == '__main__':
    main()

Solution (Python):

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



ide_ele = -1      


class SegTree:
    """
    init(init_val, ide_ele): 配列init_valで初期化 O(N)
    update(k, x): k番目の値をxに更新 O(logN)
    query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN)
    """
    def __init__(self, init_val, segfunc, ide_ele):
        """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x): 
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r): 
        """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

      




















N, K = map(int,input().split())
Num_max = 3*10**5 + 1

A = [int(input()) for _ in range(N)]


st = SegTree([0 for _ in range(Num_max+4)], segfunc, ide_ele) 

st.update(A[0], 0)  
for i in range(N):
  l = st.query(max(A[i] - K, 0), min(A[i] + K+1, Num_max)) 
  st.update(A[i], l+1)  

print(st.query(0, Num_max))

Solution (Python):
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 = -1 

N , K = map(int,input().split())
n = 300001
num =2**(300000).bit_length() 
seg=[ide_ele]*2*num
a = [int(input()) for i in range(N)]
dp = [0 for i in range(300001)]
init(dp)

for i in range(N):
    now = query(max(0,a[i]-K),min(300001,a[i]+K+1))+1
    update(a[i],now)

print(query(0,300001))

Solution (Python):


class SegmentTree():
    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

import sys
input=sys.stdin.readline
n,k=map(int,input().split())
a=[int(input()) for _ in range(n)]

st=SegmentTree(300001,0)

for ai in a:
    l=max(0,ai-k)
    r=min(300001,ai+k)
    m=st.query(l,r)
    st.update(ai,m+1)

print(st.query(0,300001))

Solution (Python):

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

ide_ele = 0

class segtree:

    def __init__(self, init_val, segfunc, ide_ele):
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num

        for i in range(n):
            self.tree[self.num + i] = init_val[i]

        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る
        """
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res


N, K = map(int, input().split())
T = []
for i in range(N):
    a = int(input())
    T.append(a)

M = max(T)+1
A = [0]*M
s_tree = segtree(A, segfunc, ide_ele)
for i in range(N):
    a = T[i]
    p = s_tree.query(max(a - K, 0), min(a + K + 1, M))
    s_tree.update(a, p + 1)

print(s_tree.query(0, M))

Solution (Python):
class SegTree:
    def __init__(self,arr,func,unit):
        self.func = func
        self.unit = unit
        n = 1
        while n < len(arr):
            n *= 2
        self.n = n
        nodes = [unit]*(2*n-1)
        nodes[n-1:n-1+len(arr)] = arr
        for i in range(n-2,-1,-1):
            nodes[i] = func(nodes[2*i+1],nodes[2*i+2])
        self.nodes = nodes

    def update(self,i,val):
        i += self.n-1
        self.nodes[i] = val
        while i >= 0:
            i = (i - 1) // 2
            self.nodes[i] = self.func(self.nodes[2*i+1], self.nodes[2*i+2])

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

n, k = map(int, input().split())
A = [int(input()) for i in range(n)]

MAX = 300001

segt = SegTree([0] * MAX, lambda x, y: max(x, y), 0)
for a in A:
    l = max(0, a - k)
    r = min(MAX, a + k + 1)
    m = segt.query(l, r)
    segt.update(a, m + 1)

print(segt.query(0, MAX))

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

def I(): return int(input())
def MI(): return map(int, input().split())
def LI(): return list(map(int, input().split()))

"""
最後のお値にしか依存しない
"""
def main():
    mod=10**9+7
    class Segtree:
        def __init__(self, A, ide_ele, initialize = True, segf = max):
            self.N = len(A)
            self.N0 = 2**(self.N-1).bit_length()
            self.ide_ele = ide_ele
            self.segf = segf
            if initialize:
                self.data = [ide_ele]*self.N0 + A + [ide_ele]*(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 = [ide_ele]*(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.ide_ele
            t = self.ide_ele
            while L < R:
                if L & 1:
                    s = self.segf(s,self.data[L])
                    L += 1
                if R & 1:
                    R -= 1
                    t = self.segf(self.data[R],t)
                L >>= 1
                R >>= 1
            return self.segf(s,t)

        
        
        
        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:
                pre = self.ide_ele
                for idx in (SR + SL[::-1]):
                    if check(self.segf(self.data[idx], pre)):
                        break
                    else:
                        pre = self.segf(self.data[idx], pre)
                else:
                    return None
                while idx < self.N0:
                    if check(self.segf(self.data[2*idx+1], pre)):
                        idx = 2*idx + 1
                    else:
                        pre = self.segf(self.data[2*idx+1], pre)
                        idx = 2*idx
                return idx - self.N0
            else:
                pre = self.ide_ele
                for idx in (SL + SR[::-1]):
                    if not check(self.segf(pre, self.data[idx])):
                        pre = self.segf(pre, self.data[idx])
                    else:
                        break
                else:
                    return None
                while idx < self.N0:
                    if check(self.segf(pre, self.data[2*idx])):
                        idx = 2*idx
                    else:
                        pre = self.segf(pre, self.data[2*idx])
                        idx = 2*idx + 1
                return idx - self.N0
            
    N,K=MI()
    M=3*10**5
    seg=Segtree([0]*(M+5), 0, segf=max)
    
    for i in range(N):
        a=I()
        l=max(a-K,0)
        r=min(M,a+K)
        temp=seg.query(l,r+1)
        seg.update(a,temp+1)
        
    ans=seg.query(0,M+1)
    print(ans)

main()

Solution (Python):
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**9)

def solve():
    INF = float('inf')

    idEle = -INF  
    def _binOpe(x, y):
        return x if x >= y else y  
    def makeSegTree(numEle):
        numPow2 = 2 ** (numEle-1).bit_length()
        data = [idEle] * (2*numPow2)
        return data, numPow2
    def setInit(As):
        for iST, A in enumerate(As, numPow2):
            data[iST] = A
        for iST in reversed(range(1, numPow2)):
            data[iST] = _binOpe(data[2*iST], data[2*iST+1])
    def _update1(iA, A):
        iST = iA + numPow2
        data[iST] = A  
    def update(iA, A):
        _update1(iA, A)
        iST = iA + numPow2
        while iST > 1:
            iST >>= 1
            data[iST] = _binOpe(data[2*iST], data[2*iST+1])
    def getValue(iSt, iEn):
        L = iSt + numPow2
        R = iEn + numPow2
        ans = idEle
        while L < R:
            if L & 1:
                ans = _binOpe(ans, data[L])
                L += 1
            if R & 1:
                R -= 1
                ans = _binOpe(ans, data[R])
            L >>= 1
            R >>= 1
        return ans


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

    maxA = max(As)

    data, numPow2 = makeSegTree(maxA+1)
    setInit([0]*(maxA+1))

    for A in As:
        L, R = A-K, A+K
        if L < 0:
            L = 0
        if R > maxA:
            R = maxA
        v = getValue(L, R+1)
        update(A, v+1)

    ans = getValue(0, maxA+1)
    print(ans)


solve()

Solution (Python):
n,k=map(int,input().split())
a=[int(input()) for _ in range(n)]
l=[[] for i in range(n)]

l[0].append(a[0])
ans=0
for ai in a[1:]:
  for i in reversed(range(ans+1)): 
    for li in l[i]:
      if -k<=(li-ai)<=k:
        ans=max(ans,i+1)
        l[i+1].append(ai)
        break
    else:
      continue
    break
  else:
    l[0].append(ai)

print(ans+1)

Solution (Python):
class SegTree:
	"""
	1-indexed
	"""
	def __init__(self,size,funcComp,funcUpd,init_val,undef):
		self.specSize = size
		self.datSize = 1
		self.compareFunc = funcComp		
		self.updateFunc = funcUpd		
		self.INIT_VAL = init_val	
		self.UNDEFINED_VAL = undef	
		
		self.datSize = 2**size.bit_length()

		
		self.datTree = [self.INIT_VAL for _ in range(2*self.datSize+1)]

	def update(self, i, val ):
		"""
		i: index(1-indexed)
		bottom-up
		"""
		
		
		i += self.datSize
		self.datTree[i] = self.updateFunc(self.datTree[i],val)
		while 0 < i:
			i >>= 1
			self.datTree[i] = self.compareFunc( self.datTree[i<<1|0], self.datTree[i<<1|1] )

	def query(self,a,b):
		""" get minimun/maximum value of range[a,b)
		non-recursive
		bottom-up
		all 1-indexed
		"""
		ret = self.UNDEFINED_VAL

		a += self.datSize
		b += self.datSize
		while a < b:

			if b & 1:
				
				b -= 1
				ret = self.compareFunc(ret, self.datTree[b])

			if a & 1:

				
				ret = self.compareFunc(ret, self.datTree[a])
				a += 1

			a >>= 1; b >>= 1

		return ret

	def printLeaf(self):
		print(self.datTree[self.datSize-1:])

def update(x,val):
	return val


def LongestSeaquence(A,K):
	N = len(A)
	lis = 0

	
	MAX_A = max(A)
	tree = SegTree(MAX_A,max,update,0,-1e18)
	

	for n in range(N):
		x = A[n]
		l = max(0,x-K)
		r = min(MAX_A,x+K)
		tmp = tree.query(l,r+1)+1
		tree.update( x, tmp )
		

	lis=tree.query(0,MAX_A)

	return lis

def main():
	N,K = map(int,input().split())
	A = [ int(input()) for _ in range(N)]

	print(LongestSeaquence(A,K))



if __name__ == "__main__":
	main()

Solution (Python):

class SegTree:
    def __init__(self, segfunc, e, v, init_val = None):
        """
        segfunc: function 区間にしたい操作\n
        e: Any 単位元\n
        v: int or List 要素数か格納する配列\n
        init_val: Any 初期値
        """
        self.segfunc = segfunc
        self.e = e
        self.init_val = init_val if init_val != None else e
        if isinstance(v, int):
            v = [self.init_val] * v
        self.n = len(v)
        self.log = (self.n).bit_length()
        self.size = 1 << self.log
        self.tree = [e] * 2 * self.size
        
        
        for i in range(self.n):
            self.tree[self.size + i] = v[i]
        for i in range(self.size - 1, 0, -1):
            self._update(i)

    def set(self, k, x) -> None:
        """
        k番目の値をxに更新\n
        k: index(0-indexed)\n
        x: update value
        """
        k += self.size
        self.tree[k] = x
        for i in range(1, self.log + 1):
            self._update(k >> i)

    def get(self, k):
        """
        a[k]を返す\n
        k: index(0-indexed)
        """
        assert 0 <= k < self.size
        return self.tree[k + self.size]

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る\n
        l: index(0-indexed)\n
        r: index(0-indexed)
        """
        res = self.e
        l += self.size
        r += self.size
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

    def all_query(self):
        """
        全範囲にsegfuncしたものを得る
        """
        return self.tree[1]

    

    def _update(self, k):
        self.tree[k] = self.segfunc(self.tree[k * 2], self.tree[k * 2 + 1])






def main():
    N, K = map(int, input().split())
    A = [int(input()) for _ in range(N)]

    MAX_A = 300005

    dp = SegTree(max, 0, MAX_A, 0)
    for i in range(N):
        x = A[i]
        now = dp.query(max(0, x - K), min(x + K + 1, MAX_A)) + 1
        dp.set(x, now)

    ans = dp.all_query()
    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):

class SegTree:
    def __init__(self, segfunc, e, v, init_val = None):
        """
        segfunc: function 区間にしたい操作\n
        e: Any 単位元\n
        v: int or List 要素数か格納する配列\n
        init_val: Any 初期値
        """
        self.segfunc = segfunc
        self.e = e
        self.init_val = init_val if init_val != None else e
        if isinstance(v, int):
            v = [self.init_val] * v
        self.n = len(v)
        self.log = (self.n).bit_length()
        self.size = 1 << self.log
        self.tree = [e] * 2 * self.size
        
        
        for i in range(self.n):
            self.tree[self.size + i] = v[i]
        for i in range(self.size - 1, 0, -1):
            self._update(i)

    def set(self, k, x) -> None:
        """
        k番目の値をxに更新\n
        k: index(0-indexed)\n
        x: update value
        """
        k += self.size
        self.tree[k] = x
        for i in range(1, self.log + 1):
            self._update(k >> i)

    def get(self, k):
        """
        a[k]を返す\n
        k: index(0-indexed)
        """
        assert 0 <= k < self.size
        return self.tree[k + self.size]

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る\n
        l: index(0-indexed)\n
        r: index(0-indexed)
        """
        res = self.e
        l += self.size
        r += self.size
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

    def all_query(self):
        """
        全範囲にsegfuncしたものを得る
        """
        return self.tree[1]

    

    def _update(self, k):
        self.tree[k] = self.segfunc(self.tree[k * 2], self.tree[k * 2 + 1])






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

MAX_A = 300005

dp = SegTree(max, 0, MAX_A, 0)
for i in range(N):
    x = A[i]
    now = dp.query(max(0, x - K), min(x + K + 1, MAX_A)) + 1
    dp.set(x, now)

ans = dp.all_query()
print(ans)

Solution (Python):

class SegTree:
    def __init__(self, segfunc, e, v, init_val = None):
        """
        segfunc: function 区間にしたい操作\n
        e: Any 単位元\n
        v: int or List 要素数か格納する配列\n
        init_val: Any 初期値
        """
        self.segfunc = segfunc
        self.e = e
        self.init_val = init_val if init_val != None else e
        if isinstance(v, int):
            v = [self.init_val] * v
        self.n = len(v)
        self.log = (self.n).bit_length()
        self.size = 1 << self.log
        self.tree = [e] * 2 * self.size
        
        
        self.tree[self.size:self.size + self.n] = v
        for i in range(self.size - 1, 0, -1):
            self._update(i)

    def set(self, k, x) -> None:
        """
        k番目の値をxに更新\n
        k: index(0-indexed)\n
        x: update value
        """
        k += self.size
        self.tree[k] = x
        for i in range(1, self.log + 1):
            self._update(k >> i)

    def get(self, k):
        """
        a[k]を返す\n
        k: index(0-indexed)
        """
        assert 0 <= k < self.size
        return self.tree[k + self.size]

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る\n
        l: index(0-indexed)\n
        r: index(0-indexed)
        """
        res = self.e
        l += self.size
        r += self.size
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

    def all_query(self):
        """
        全範囲にsegfuncしたものを得る
        """
        return self.tree[1]

    

    def _update(self, k):
        self.tree[k] = self.segfunc(self.tree[k * 2], self.tree[k * 2 + 1])






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

MAX_A = 300005

dp = SegTree(max, 0, MAX_A, 0)
for i in range(N):
    x = A[i]
    now = dp.query(max(0, x - K), min(x + K + 1, MAX_A)) + 1
    dp.set(x, now)

ans = dp.all_query()
print(ans)

Solution (Python):
def op(a,b):
    return max(a,b)

class segmentTree:
    def __init__(self,n,op,init_value):
        dataLen=1 << (n - 1).bit_length()
        self.data=[init_value]*(2*dataLen)
        self.op=op
        self.length=dataLen
    def getIdx(self,left,right):
        idxs=[]
        l=left
        r=right
        while True:
            idx=1
            valueL=0
            valueR=self.length-1
            while l!=valueL or valueR>=r:
                if l<=(valueR+valueL)//2:
                    valueR-=(valueR-valueL+1)//2
                    idx*=2
                else:
                    valueL+=(valueR-valueL+1)//2
                    idx=idx*2+1
            idxs.append(idx)
            if valueR==r-1:
                break
            l=valueR+1
        return idxs
    def get(self,n):
        return self.data[n+self.length]

    def set(self,n,value):
        idx1=n+self.length
        self.data[idx1]=value
        while idx1!=1:
            idx2=idx1^1
            if idx1>idx2:
                idx1,idx2=idx2,idx1
            self.data[idx1//2]=self.op(self.data[idx1],self.data[idx2])
            idx1//=2
    def query(self,l,r):
        idxs=self.getIdx(l,r)
        ret=self.data[idxs[0]]
        for idx in idxs:
            ret=self.op(ret,self.data[idx])
        return ret


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

N=300000
seg = segmentTree(N, op, 0)

for i in A:
  l=min(N,max(0,i-K))
  r=max(0,min(N,i+K))
  v=seg.query(l,r+1)
  seg.set(i,v+1)
print(seg.query(0,N))

Solution (Python):

class SegTree:
    def __init__(self, segfunc, e, v, init_val = None):
        """
        segfunc: function 区間にしたい操作\n
        e: Any 単位元\n
        v: int or List 要素数か格納する配列\n
        init_val: Any 初期値
        """
        self.segfunc = segfunc
        self.e = e
        self.init_val = init_val if init_val != None else e
        if isinstance(v, int):
            v = [self.init_val] * v
        self.n = len(v)
        self.log = (self.n).bit_length()
        self.size = 1 << self.log
        self.tree = [e] * 2 * self.size
        
        
        for i in range(self.n):
            self.tree[self.size + i] = v[i]
        for i in range(self.size - 1, 0, -1):
            self._update(i)

    def set(self, k, x) -> None:
        """
        k番目の値をxに更新\n
        k: index(0-indexed)\n
        x: update value
        """
        k += self.size
        self.tree[k] = x

        for i in range(1, self.log + 1):
            self._update(k >> i)

    def get(self, k):
        """
        a[k]を返す\n
        k: index(0-indexed)
        """
        assert 0 <= k < self.size
        return self.tree[k + self.size]

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る\n
        l: index(0-indexed)\n
        r: index(0-indexed)
        """
        res = self.e
        l += self.size
        r += self.size
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

    def all_query(self):
        """
        全範囲にsegfuncしたものを得る
        """
        return self.tree[1]

    

    def _update(self, k):
        self.tree[k] = self.segfunc(self.tree[k * 2], self.tree[k * 2 + 1])






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

MAX_A = 300005

dp = SegTree(max, 0, MAX_A, 0)
for i in range(N):
    x = A[i]
    now = dp.query(max(0, x - K), min(x + K + 1, MAX_A)) + 1
    dp.set(x, now)

ans = dp.all_query()
print(ans)

Solution (Python):
def op(a,b):
    return max(a,b)

class segmentTree:
    def __init__(self,n,op,init_value):
        dataLen=1 << (n - 1).bit_length()
        self.data=[init_value]*(2*dataLen)
        self.op=op
        self.length=dataLen
    def getIdx(self,left,right):
        idxs=[]
        l=left
        r=right
        while True:
            idx=1
            valueL=0
            valueR=self.length-1
            while l!=valueL or valueR>=r:
                if l<=(valueR+valueL)//2:
                    valueR-=(valueR-valueL+1)//2
                    idx*=2
                else:
                    valueL+=(valueR-valueL+1)//2
                    idx=idx*2+1
            idxs.append(idx)
            if valueR==r-1:
                break
            l=valueR+1
        return idxs
    def get(self,n):
        return self.data[self.getIdx(n,n+1)[0]]

    def set(self,n,value):
        if n<0 or n>=self.length:
          return False
        idx1=self.getIdx(n,n+1)[0]
        self.data[idx1]=value
        while idx1!=1:
            idx2=idx1^1
            if idx1>idx2:
                idx1,idx2=idx2,idx1
            self.data[idx1//2]=self.op(self.data[idx1],self.data[idx2])
            idx1//=2
        return True
    def query(self,l,r):
        idxs=self.getIdx(l,r)
        ret=self.data[idxs[0]]
        for idx in idxs:
            ret=self.op(ret,self.data[idx])
        return ret


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

N=300000
seg = segmentTree(N, op, 0)

for i in A:
  l=min(N,max(0,i-K))
  r=max(0,min(N,i+K))
  v=seg.query(l,r+1)
  seg.set(i,v+1)
print(seg.query(0,N))