Problem:
 Score : 400 points    Problem Statement Along a road running in an east-west direction, there are A shrines and B temples.
The i -th shrine from the west is located at a distance of s_i meters from the west end of the road, and the i -th temple from the west is located at a distance of t_i meters from the west end of the road.  Answer the following Q queries:   Query i ( 1 \leq i \leq Q ): If we start from a point at a distance of x_i meters from the west end of the road and freely travel along the road, what is the minimum distance that needs to be traveled in order to visit one shrine and one temple? (It is allowed to pass by more shrines and temples than required.)       Constraints  1 \leq A, B \leq 10^5  1 \leq Q \leq 10^5  1 \leq s_1 < s_2 < ... < s_A \leq 10^{10}  1 \leq t_1 < t_2 < ... < t_B \leq 10^{10}  1 \leq x_i \leq 10^{10}  s_1, ..., s_A, t_1, ..., t_B, x_1, ..., x_Q are all different.  All values in input are integers.         Input Input is given from Standard Input in the following format:  A  B  Q  s_1  :  s_A  t_1  :  t_B  x_1  :  x_Q       Output Print Q lines. The i -th line should contain the answer to the i -th query.        Sample Input 1 2 3 4
100
600
400
900
1000
150
2000
899
799      Sample Output 1 350
1400
301
399  There are two shrines and three temples. The shrines are located at distances of 100, 600 meters from the west end of the road, and the temples are located at distances of 400, 900, 1000 meters from the west end of the road.   Query 1 : If we start from a point at a distance of 150 meters from the west end of the road, the optimal move is first to walk 50 meters west to visit a shrine, then to walk 300 meters east to visit a temple.  Query 2 : If we start from a point at a distance of 2000 meters from the west end of the road, the optimal move is first to walk 1000 meters west to visit a temple, then to walk 400 meters west to visit a shrine. We will pass by another temple on the way, but it is fine.  Query 3 : If we start from a point at a distance of 899 meters from the west end of the road, the optimal move is first to walk 1 meter east to visit a temple, then to walk 300 meters west to visit a shrine.  Query 4 : If we start from a point at a distance of 799 meters from the west end of the road, the optimal move is first to walk 199 meters west to visit a shrine, then to walk 200 meters west to visit a temple.        Sample Input 2 1 1 3
1
10000000000
2
9999999999
5000000000      Sample Output 2 10000000000
10000000000
14999999998  The road is quite long, and we may need to travel a distance that does not fit into a 32 -bit integer.

Solution (Python):

import sys
from bisect import bisect_left, bisect_right
from operator import itemgetter
from fractions import gcd
from math import ceil, floor, sqrt
from copy import deepcopy
from collections import Counter, deque
import heapq
from functools import reduce
from random import shuffle
import cProfile
sys.setrecursionlimit(200000)





input = sys.stdin.readline
def ii(): return int(input())
def mi(): return map(int, input().rstrip().split())
def lmi(): return list(map(int, input().rstrip().split()))
def li(): return list(input().rstrip())
def debug(*args, sep=" ", end="\n"): print("debug:", *args, file=sys.stderr, sep=sep, end=end) if not __debug__ else None
def exit(*arg): print(*arg); sys.exit()



class Avltree:
    """
    AVL木

    Methods
    -------
        search(x: int) -> Union(int)
            ◯.data == x のものが存在するある場合それを出力、ない場合 None を返す
        insert(x: int) -> None
            ◯.data == x がない場合 ◯.data == x なる頂点を作る。ある場合はなにもしない（上書きしない）
        y.to_s() -> int
            頂点yのdataを返す
        y.left_s() -> Union(int, key=None)
            頂点yのleftを返す(ない場合は key)
        search_lower(x: int, key_lower) -> int
            ○.data が x より小さいものの中で最も大きいものを出力、ない場合 key_lower を返す
        search_higher(x:int , key_higher) -> int
            ○.data が x より大きいものの中で最も小さいものを出力、ない場合 key_higher を返す
    """

    def __init__(self, key=None):
        self.key = key
        self.left = None
        self.right = None
        self.balance = "Even"

    def search(self, key):
        node = self
        while node is not None:
            if node.key == key:
                return node  
            if node.key > key:
                node = node.left
            elif node.key < key:
                node = node.right
        return None

    def search_lower(self, key, key_lower):
        node = self
        if node.key is None:
            return key_lower
        ans = key_lower
        while node is not None:
            if node.key < key:
                if ans < node.key:
                    ans = node.key
                node = node.right
            elif node.key >= key:
                node = node.left
        return ans

    def search_higher(self, key, key_higher):
        node = self
        if node.key is None:
            return key_higher
        ans = key_higher
        while node is not None:
            if node.key > key:
                if ans > node.key:
                    ans = node.key
                node = node.left
            elif node.key <= key:
                node = node.right
        return ans


    def end_lower(self, end_lower_key):
        node = self
        while node.left is not None:
            node = node.left
        return node.key

    def end_higher(self, end_higher_key):
        node = self
        while node.right is not None:
            node = node.right
        return node.key


    def DoubleRightRotation(self):
        tl = self.left
        self.left = tl.right.right
        tl.right.right = self  
        tlr = tl.right
        tl.right = tlr.left
        tlr.left = tl
        if tlr.balance == "Left":
            tlr.right.balance = "Right"
            tlr.left.balance = "Even"
        elif tlr.balance == "Right":
            tlr.right.balance = "Even"
            tlr.left.balance = "Left"
        elif tlr.balance == "Even":
            tlr.right.balance = "Even"
            tlr.left.balance = "Even"
        tlr.balance = "Even"
        return tlr
    def DoubleLeftRotation(self):
        tr = self.right
        self.right = tr.left.left
        tr.left.left = self
        trl = tr.left
        tr.left = trl.right
        trl.right = tr
        if trl.balance == "Right":
            trl.left.balance = "Left"
            trl.right.balance = "Even"
        elif trl.balance == "Left":
            trl.left.balance = "Even"
            trl.right.balance = "Right"
        elif trl.balance == "Even":
            trl.left.balance = "Even"
            trl.right.balance = "Even"
        trl.balance = "Even"
        return trl
    def SingleLeftRotation(self):
        tr = self.right
        tr.balance = "Even"
        self.balance = "Even"
        self.right = tr.left
        tr.left = self
        return tr
    def SingleRightRotation(self):
        tl = self.left
        tl.balance = "Even"
        self.balance = "Even"
        self.left = tl.right
        tl.right = self
        return tl
    def replace(self, p, v):  
        if p.left == self:
            p.left = v
        else:
            p.right = v
    def insert(self, key):  
        if self.key is None:  
            self.key = key
            return self
        if key < self.key:
            if self.left is None:
                self.left = Avltree(key)
            else:
                self.left.insertx(self, key)
        elif key > self.key:
            if self.right is None:
                self.right = Avltree(key)
            else:
                self.right.insertx(self, key)
        else:  
            pass  
    def insertx(self, p, key):  
        node = self
        s = []
        while True:
            if node.key > key:
                s.append((node, -1))
                if node.left is None:
                    node.left = Avltree(key)
                    node = node.left
                    break
                else:
                    node = node.left
            elif node.key < key:
                s.append((node, 1))
                if node.right is None:
                    node.right = Avltree(key)
                    node = node.right
                    break
                else:
                    node = node.right
        while len(s) != 0:
            node, direct = s.pop()
            if len(s) != 0:
                par = s[-1][0]
            else:
                par = p
            if direct == -1:
                if node.balance == "Right":
                    node.balance = "Even"
                    break
                elif node.balance == "Even":
                    node.balance = "Left"
                elif node.balance == "Left":
                    if node.left.balance == "Right":
                        node.replace(par, node.DoubleRightRotation())
                    elif node.left.balance == "Left":
                        node.replace(par, node.SingleRightRotation())
                    break
            elif direct == 1:
                if node.balance == "Left":
                    node.balance = "Even"
                    break
                elif node.balance == "Even":
                    node.balance = "Right"
                elif node.balance == "Right":
                    if node.right.balance == "Left":
                        node.replace(par, node.DoubleLeftRotation())
                    elif node.right.balance == "Right":
                        node.replace(par, node.SingleLeftRotation())
                    break

    def to_s(self):
        return self.key
    def left_s(self):
        if self.left is None:
            return None
        return (self.left).key
    def right_s(self):
        if self.right is None:
            return None
        return (self.right).key




def main():
    rb1 = Avltree()
    a, b, q = map(int, input().split())

    rb2 = Avltree()
    for i in range(a):
        s = ii()
        rb1.insert(s)
    for i in range(b):
        t = ii()
        rb2.insert(t)
    
    
    for i in range(q):
        x = ii()
        s1 = rb1.search_lower(x, -10**18)
        s2 = rb1.search_higher(x, 10**18)
        t1 = rb2.search_lower(x, -10**18)
        t2 = rb2.search_higher(x, 10**18)
        
        res = 10**18
        for S in [s1, s2]:
            for T in [t1, t2]:
                d1, d2 = abs(S - x) + abs(T - S), abs(T - x) + abs(S - T)
                res = min(res, d1, d2)
        print(res)




if __name__ == '__main__':
    
    main()

Solution (Python):
import bisect

def search_idx_options(input_list, input_list_len, target_val):
  idx_left = bisect.bisect_left(input_list, target_val)
  if idx_left == -1: idxs = [0]
  elif  idx_left == input_list_len: idxs = [input_list_len-1]
  else: idxs = [idx_left-1, idx_left]
  return idxs

A,B,Q = map(int,input().split())
S = [int(input()) for _ in range(A)]
T = [int(input()) for _ in range(B)]

for x in [int(input()) for _ in range(Q)]:
  ans_list = []

  for s_idx in search_idx_options(S, A, x):
    if s_idx >= A: continue
    for t_idx in search_idx_options(T, B, S[s_idx]):
      if t_idx >= B: continue
      ans_list.append(abs(x-S[s_idx]) + abs(S[s_idx]-T[t_idx]))

  for t_idx in search_idx_options(T, B, x):
    if t_idx >= B: continue
    for s_idx in search_idx_options(S, A, T[t_idx]):
      if s_idx >= A: continue
      ans_list.append(abs(x-T[t_idx]) + abs(T[t_idx]-S[s_idx]))
 
  print(min(ans_list))

Solution (Python):
import bisect
def check(x,s,t):
    s_index = bisect.bisect_left(s,x)
    
    sr = s[s_index]
    sl = s[s_index-1]
    t_index = bisect.bisect_left(t,x)
    tr = t[t_index]
    tl = t[t_index-1]
    shrine = [sr,sl]
    temp = [tr,tl]
    ans = 10**20
    for i in range(2):
        for j in range(2):
            for l in range(2):
                if i == 0:
                    can = abs(shrine[j]-x)
                    can += abs(temp[l]-shrine[j])
                else:
                    can = abs(temp[l]-x)
                    can += abs(shrine[j]-temp[l])
                ans = min(ans,can)
    print(ans)
    


def main():
    a,b,q = map(int,input().split())
    s = [int(input()) for _ in range(a)]
    s.append(10**20)
    s.insert(0,-10**20)
    t = [int(input()) for _ in range(b)]
    t.append(10**20)
    t.insert(0,-10**20)
    x = [int(input()) for _ in range(q)]

    for i in range(q):
        check(x[i],s,t)

if __name__ == "__main__":
    main()

Solution (Python):

import sys
from bisect import bisect_left, bisect_right
from operator import itemgetter
from fractions import gcd
from math import ceil, floor, sqrt
from copy import deepcopy
from collections import Counter, deque
import heapq
from functools import reduce
from random import shuffle
sys.setrecursionlimit(200000)





input = sys.stdin.readline
def ii(): return int(input())
def mi(): return map(int, input().rstrip().split())
def lmi(): return list(map(int, input().rstrip().split()))
def li(): return list(input().rstrip())
def debug(*args, sep=" ", end="\n"): print("debug:", *args, file=sys.stderr, sep=sep, end=end) if not __debug__ else None
def exit(*arg): print(*arg); sys.exit()


class RBNode:
    def __init__(self, val, is_red=True, parent=None, left=None, right=None):
        self.val = val
        self.parent = parent
        self.left = left
        self.right = right
        self.color = is_red


class RBTree:
    def __init__(self):
        self.root = None

    def left_rotate(self, node):
        
        right_node = node.right
        if right_node is None:
            return
        else:
            
            node.right = right_node.left
            if right_node.left is not None:
                right_node.left.parent = node
            right_node.parent = node.parent
            
            if node.parent is None:
                self.root = right_node
            elif node is node.parent.left:
                node.parent.left = right_node
            else:
                node.parent.right = right_node
            right_node.left = node
            node.parent = right_node

    def right_rotate(self, node):
        
        left_node = node.left
        if left_node is None:
            return
        else:
            
            node.left = left_node.right
            if left_node.right is not None:
                left_node.right.parent = node
            left_node.parent = node.parent
            
            if node.parent is None:
                self.root = left_node
            elif node is node.parent.left:
                node.parent.left = left_node
            else:
                node.parent.right = left_node
            left_node.right = node
            node.parent = left_node

    def insert(self, node):
        
        root = self.root
        insert_node_parent = None
        
        while root is not None:
            insert_node_parent = root
            if insert_node_parent.val < node.val:
                root = root.right
            else:
                root = root.left
        
        node.parent = insert_node_parent
        if insert_node_parent is None:
            
            self.root = node
        elif insert_node_parent.val > node.val:
            
            insert_node_parent.left = node
        else:
            insert_node_parent.right = node
        node.left = None
        node.right = None
        node.color = 1
        
        self.fix_insert(node)

    def fix_insert(self, node):
        
        if node.parent is None:
            node.color = 0
            self.root = node
            return
            
        
        while node.parent and node.parent.color == 1:
            if node.parent is node.parent.parent.left:
                uncle_node = node.parent.parent.right
                if uncle_node and uncle_node.color == 1:
                    
                    
                    
                    node.parent.color = 0
                    node.parent.parent.right.color = 0
                    node.parent.parent.color = 1
                    node = node.parent.parent
                    continue
                elif node is node.parent.right:
                    
                    
                    
                    node = node.parent
                    self.left_rotate(node)
                
                
                node.parent.color = 0
                node.parent.parent.color = 1
                self.right_rotate(node.parent.parent)
            else:
                uncle_node = node.parent.parent.left
                if uncle_node and uncle_node.color == 1:
                    
                    
                    
                    node.parent.color = 0
                    node.parent.parent.left.color = 0
                    node.parent.parent.color = 1
                    node = node.parent.parent
                    continue
                elif node is node.parent.left:
                    
                    
                    
                    node = node.parent
                    self.right_rotate(node)
                
                
                node.parent.color = 0
                node.parent.parent.color = 1
                self.left_rotate(node.parent.parent)
        self.root.color = 0

    def transplant(self, node_u, node_v):
        """
        replace u with v
        :param node_u: replaced node
        :param node_v:
        :return: None
        """
        if node_u.parent is None:
            self.root = node_v
        elif node_u is node_u.parent.left:
            node_u.parent.left = node_v
        elif node_u is node_u.parent.right:
            node_u.parent.right = node_v
        
        if node_v:
            node_v.parent = node_u.parent

    def find(self, key):
        node = self.root
        while node is not None:
            if node.val < key:
                node = node.right
            elif node.val > key:
                node = node.left
            else:
                return node
        return None

    def maximum(self, node):
        """
        find the max node when node regard as a root node
        :param node:
        :return: max node
        """
        temp_node = node
        while temp_node.right:
            temp_node = temp_node.right
        return temp_node

    def minimum(self, node):
        """
        find the minimum node when node regard as a root node
        :param node:
        :return: minimum node
        """
        temp_node = node
        while temp_node.left:
            temp_node = temp_node.left
        return temp_node

    def search_higher(self, key, key_higher=None):
        node = self.root
        if node.val is None:
            return key_higher
        ans = key_higher
        while node is not None:
            if node.val > key:
                ans = min(ans, node.val)
                node = node.left
            elif node.val <= key:
                node = node.right
        return ans

    def search_lower(self, key, key_lower=None):
        node = self.root
        if node.val is None:
            return key_lower
        ans = key_lower
        while node is not None:
            if node.val < key:
                ans = max(ans, node.val)
                node = node.right
            elif node.val >= key:
                node = node.left
        return ans

    def delete(self, node):
        
        node_color = node.color
        if node.left is None:
            temp_node = node.right
            self.transplant(node, node.right)
        elif node.right is None:
            temp_node = node.left
            self.transplant(node, node.left)
        else:
            
            node_min = self.minimum(node.right)
            node_color = node_min.color
            temp_node = node_min.right
            
            if node_min.parent != node:
                self.transplant(node_min, node_min.right)
                node_min.right = node.right
                node_min.right.parent = node_min
            self.transplant(node, node_min)
            node_min.left = node.left
            node_min.left.parent = node_min
            node_min.color = node.color
        
        if node_color == 0:
            self.delete_fixup(temp_node)

    def delete_fixup(self, node):
        
        while node != self.root and node.color == 0:
            
            if node == node.parent.left:
                
                node_brother = node.parent.right

                
                
                if node_brother.color == 1:
                    node_brother.color = 0
                    node.parent.color = 1
                    self.left_rotate(node.parent)
                    node_brother = node.parent.right

                
                if (node_brother.left is None or node_brother.left.color == 0) and (
                        node_brother.right is None or node_brother.right.color == 0):
                    node_brother.color = 1
                    node = node.parent
                else:

                    
                    if node_brother.right is None or node_brother.right.color == 0:
                        node_brother.color = 1
                        node_brother.left.color = 0
                        self.right_rotate(node_brother)
                        node_brother = node.parent.right

                    
                    node_brother.color = node.parent.color
                    node.parent.color = 0
                    node_brother.right.color = 0
                    self.left_rotate(node.parent)
                node = self.root
                break
            else:
                node_brother = node.parent.left
                if node_brother.color == 1:
                    node_brother.color = 0
                    node.parent.color = 1
                    self.left_rotate(node.parent)
                    node_brother = node.parent.right
                if (node_brother.left is None or node_brother.left.color == 0) and (
                        node_brother.right is None or node_brother.right.color == 0):
                    node_brother.color = 1
                    node = node.parent
                else:
                    if node_brother.left is None or node_brother.left.color == 0:
                        node_brother.color = 1
                        node_brother.right.color = 0
                        self.left_rotate(node_brother)
                        node_brother = node.parent.left
                    node_brother.color = node.parent.color
                    node.parent.color = 0
                    node_brother.left.color = 0
                    self.right_rotate(node.parent)
                node = self.root
                break
        node.color = 0

    def output(self):
        res = []
        if not self.root:
            print()
        que = deque()
        root = self.root
        que.append(root)
        while que:
            root = que.popleft()
            if root.parent:
                res.append({'parent': root.parent.val, 'val': root.val, 'color': root.color})
            else:
                res.append({'val': root.val, 'color': root.color})
            if root.left is not None:
                que.append(root.left)
            if root.right is not None:
                que.append(root.right)
        print(*res, sep="\n")
        return



def main():
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    rb1 = RBTree()
    a, b, q = map(int, input().split())

    rb2 = RBTree()
    for i in range(a):
        s = ii()
        rb1.insert(RBNode(s))
    for i in range(b):
        t = ii()
        rb2.insert(RBNode(t))
    
    
    for i in range(q):
        x = ii()
        s1 = rb1.search_lower(x, -10**18)
        s2 = rb1.search_higher(x, 10**18)
        t1 = rb2.search_lower(x, -10**18)
        t2 = rb2.search_higher(x, 10**18)
        
        res = 10**18
        for S in [s1, s2]:
            for T in [t1, t2]:
                d1, d2 = abs(S - x) + abs(T - S), abs(T - x) + abs(S - T)
                res = min(res, d1, d2)
        print(res)




if __name__ == '__main__':
    main()