Problem:


Problem I: Hard Beans

Problem

大津大学では豆が盛んです。
N個の豆が一直線上に並んでいます。
それぞれ0から順にN&minus;1まで番号がふられており、i番目の豆の硬さをaiとします。

シアン君は理想の豆の硬さをDだと考えています。しかし、シアン君は面倒くさがりなのであまり遠くにある豆を取りに行きたくありません。したがって、シアン君はl番目の豆からr番目の豆の中で硬さがDに最も近い豆を知りたいと思っています。

シアン君はQ個の質問をしてくるので、それぞれの質問に対し閉区間[l,r]番目にある　| 豆の硬さ &minus; D |　の最小値を求めるプログラムを作成してください。(ただし、| a | は aの絶対値を表します。)

Input

入力は以下の形式で与えられる。

N
a0 a1 ... aN&minus;1
Q
l0 r0 D0
l1 r1 D1
.
.
.
lQ&minus;1 rQ&minus;1 DQ&minus;1

1行目に、1つの整数Nが与えられる。2行目に、Nつの整数が空白区切りで与えられる。3行目に、クエリの数が１つの整数Qとして与えられる。続く4行から3+Q行までにクエリの値l,r,Dが与えられる。

Constraints

入力は以下の制約を満たす。

1 ≤ N ≤ 105

0 ≤ |ai| ≤ 106 (0 ≤ i ≤ N&minus;1)

1 ≤ Q ≤ 105

0 ≤ Di ≤ 106

0 ≤ li ≤ ri ≤ N&minus;1

Output

各クエリに対し、Dと[l,r]番目の豆の中で硬さDに最も近い豆の硬さとの差の絶対値を1行に出力せよ。

Sample Input1

3
1 2 3
3
0 2 2
0 2 4
0 0 2

Sample Output1

0
1
1

Sample Input2

10
4 5 0 21 9 100 12 9 0 8
5
0 3 20
2 5 100
8 9 9
5 5 10
0 9 20

Sample Output2

1
0
1
90
1



Sample input:
3
1 2 3
3
0 2 2
0 2 4
0 0 2


Sample output:
0
1
1

Submission status: Accepted

Solution code:

class SegmentTree(object):
    def __init__(self, a:list, default: int, op):
        from math import ceil, log
        real_size = len(a)
        self.elem_size = elem_size = 1<<ceil(log(real_size, 2))
        self.tree = tree = [default] * (elem_size * 2)
        tree[elem_size:elem_size + real_size] = a
        self.default = default
        self.op = op
        for i in range(elem_size - 1, 0, -1):
            tree[i] = op(tree[i<<1], tree[(i<<1)+1])
    def get_value(self, x:int, y:int):
        l, r = x+self.elem_size, y+self.elem_size
        tree, result, op = self.tree, self.default, self.op
        while l<r:
            if l & 1:
                result = op(tree[l], result)
                l += 1
            if r&1:
                r -= 1
                result = op(tree[r], result)
            l, r = l>>1, r>>1
        return result
    def set_value(self, i:int, value:int):
        k = self.elem_size + i
        self.tree[k] = value
        self.update(k)
    def update(self, i:int):
        op, tree = self.op, self.tree
        while i > 1:
            i >>= 1
            tree[i] = op(tree[i<<1], tree[(i<<1)+1])


N = int(input())
A = list(map(int, input().split()))
Q_ = int(input())
Q = []
for i in range(Q_):
    l, r, d = map(int, input().split())
    Q.append([l, r, d, i])
seg1 = SegmentTree([-1<<30]*N, -1<<30, max)
seg2 = SegmentTree(A, 1<<30, min)
from operator import itemgetter
Q.sort(key=itemgetter(2))
A = sorted(zip(A, range(N)), key=itemgetter(0))

a_idx = 0
Ans = [0] * Q_
for l, r, d, q_idx in Q:
    while a_idx < N:
        a0, a1 = A[a_idx]
        if a0 > d:
            break
        else:
            seg1.set_value(a1, a0)
            seg2.set_value(a1, 1<<30)
            a_idx += 1
    an1 = abs(seg1.get_value(l, r+1) - d)
    an2 = abs(seg2.get_value(l, r+1) - d)
    Ans[q_idx] = min(an1, an2)

print(*Ans, sep="\n")