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 in JavaScript (Node.js 12.16.1) (judge verdict: Accepted)

//↓見なくていいよ！ここから--------------------------------------------------
var read = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
var obj;
var inLine = [];
read.on('line', function(input){inLine.push(input);});
read.on('close', function(){
  obj = init(inLine);
  console.error("\n");
  var start = Date.now();
  Main();
  var end = Date.now() - start;
  myerr("time : " + (end) + "ms");
  myerr("memory : " + Math.round(process.memoryUsage().heapTotal / 1024) + "KB");
});
function makeClone(obj){return JSON.parse(JSON.stringify(obj));}
function nextInt(){return myconv(next(),1);} function nextStrArray(){return myconv(next(),2);}
function nextIntArray(){return myconv(next(),4);} function nextCharArray(){return myconv(next(),6);}
function next(){return obj.next();} function hasNext(){return obj.hasNext();}
function init(input){  
  var returnObj = {
    list : input, index : 0, max : input.length,
    hasNext : function(){return (this.index < this.max);},
    next : function(){if(!this.hasNext()){throw "ArrayIndexOutOfBoundsException これ以上ないよ";}else{var returnInput = this.list[this.index];this.index++;return returnInput;}}
  };
  return returnObj;
}
function myout(s){console.log(s);}
function myerr(s){console.error("debug:" + require("util").inspect(s,false,null));}
//[no]要素の扱い。数値型
//不明値、異常時:引数そのまま返す 1:数値へ変換
//2:半角SPで分割 4:半角SPで分割し、数値配列へ
//6:1文字で分割  7:1文字で分割し、数値配列へ
//8:半角SPで結合 9:改行で結合 0:文字なしで結合
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(" ");case 4:return i.split(" ").map(Number);case 6:return i.split("");case 7:return i.split("").map(Number);case 8:return i.join(" ");case 9:return i.join("\n");case 0:return i.join("");default:return i;}}catch(e){return i;}}

//↑見なくていいよ！ここまで--------------------------------------------------
function Main(){
	var one = nextIntArray();
	var A = one[0];
	var B = one[1];
	var X = one[2];
	var alist = new Array(A);
	var blist = new Array(B);
	for(var i = 0; i < A; i++){
		alist[i] = nextInt();
	}
	for(var i = 0; i < B; i++){
		blist[i] = nextInt();
	}
	alist.sort(function(a,b){
		return a - b;
	});
	blist.sort(function(a,b){
		return a - b;
	});
	var output = new Array(X);
	for(var i = 0; i < X; i++){
		var xi = nextInt();
		var aIndex = binarySearch(alist, xi);
		var bIndex = binarySearch(blist, xi);
		var selectA = {
			kyori : 0,
			vecOnly : 0//0:両方選択可、1:右のみ、2:左のみ
		};
		var selectB = {
			kyori : 0,
			vecOnly : 0
		};
		if(aIndex[0] == -1 || aIndex[1] == A){
			if(aIndex[0] == -1){
				selectA.kyori = alist[aIndex[1]];
				selectA.vecOnly = 1;
			}else{
				selectA.kyori = alist[aIndex[0]];
				selectA.vecOnly = 2;
			}
		}
		if(bIndex[0] == -1 || bIndex[1] == B){
			if(bIndex[0] == -1){
				selectB.kyori = blist[bIndex[1]];
				selectB.vecOnly = 1;
			}else{
				selectB.kyori = blist[bIndex[0]];
				selectB.vecOnly = 2;
			}
		}
		myerr({selectA, selectB});
		if(selectA.vecOnly != 0 && selectB.vecOnly != 0 && selectA.vecOnly == selectB.vecOnly){
			output[i] = Math.max(Math.abs(selectA.kyori - xi), Math.abs(selectB.kyori - xi));
		}else{
			var out = [];
			if(selectA.vecOnly != 0 && selectB.vecOnly == 0){
				//A(神社)だけ向きが1個確定してる
				if(selectA.vecOnly == 1){
					//右の場合
					//1:右へ素通り
					//2:左の寺に行ってから右へ
					//3:右の神社に行ってから左へ
					var pattern1 = Math.max(Math.abs(selectA.kyori - xi), Math.abs(blist[bIndex[1]] - xi));
					var pattern2 = Math.abs(blist[bIndex[0]] - xi) * 2 + Math.abs(selectA.kyori - xi);
					var pattern3 = Math.abs(selectA.kyori - xi) * 2 + Math.abs(blist[bIndex[0]] - xi);
					out.push(pattern1);out.push(pattern2);out.push(pattern3);
					output[i] = Math.min.apply(null, out);
				}else{
					//左の場合
					//1:左へ素通り
					//2:右の寺に行ってから左へ
					//3:左の神社に行ってから右へ
					var pattern1 = Math.max(Math.abs(selectA.kyori - xi), Math.abs(blist[bIndex[0]] - xi));
					var pattern2 = Math.abs(blist[bIndex[1]] - xi) * 2 + Math.abs(selectA.kyori - xi);
					var pattern3 = Math.abs(selectA.kyori - xi) * 2 + Math.abs(blist[bIndex[1]] - xi);
					out.push(pattern1);out.push(pattern2);out.push(pattern3);
					output[i] = Math.min.apply(null, out);
				}
			}else if(selectA.vecOnly == 0 && selectB.vecOnly != 0){
				//B(寺)だけ向きが1個確定してる
				if(selectB.vecOnly == 1){
					//右の場合
					//1:右へ素通り
					//2:左の神社に行ってから右へ
					//3:右の寺に行ってから左へ
					var pattern1 = Math.max(Math.abs(selectB.kyori - xi), Math.abs(alist[aIndex[1]] - xi));
					var pattern2 = Math.abs(alist[aIndex[0]] - xi) * 2 + Math.abs(selectB.kyori - xi);
					var pattern3 = Math.abs(selectB.kyori - xi) * 2 + Math.abs(alist[aIndex[0]] - xi);
					out.push(pattern1);out.push(pattern2);out.push(pattern3);
					output[i] = Math.min.apply(null, out);
				}else{
					//左の場合
					//1:左へ素通り
					//2:右の神社に行ってから左へ
					//3:左の寺に行ってから右へ
					var pattern1 = Math.max(Math.abs(selectB.kyori - xi), Math.abs(alist[aIndex[0]] - xi));
					var pattern2 = Math.abs(alist[aIndex[1]] - xi) * 2 + Math.abs(selectB.kyori - xi);
					var pattern3 = Math.abs(selectB.kyori - xi) * 2 + Math.abs(alist[aIndex[1]] - xi);
					out.push(pattern1);out.push(pattern2);out.push(pattern3);
					output[i] = Math.min.apply(null, out);
				}
			}else if(selectA.vecOnly != 0 && selectB.vecOnly != 0){
				//向かうべき寺と神社が逆方向に1個ずつしかない場合
				var pattern1 = Math.abs(selectA.kyori - xi) * 2 + Math.abs(selectB.kyori - xi);
				var pattern2 = Math.abs(selectB.kyori - xi) * 2 + Math.abs(selectA.kyori - xi);
				out.push(pattern1);out.push(pattern2);
				output[i] = Math.min.apply(null, out);
			}else{
				//パターン数多すぎ
				var pattern1 = Math.max(Math.abs(alist[aIndex[0]] - xi), Math.abs(blist[bIndex[0]] - xi));//左+左
				var pattern2 = Math.max(Math.abs(alist[aIndex[1]] - xi), Math.abs(blist[bIndex[1]] - xi));//右+右
				var pattern3 = Math.abs(alist[aIndex[0]] - xi) * 2 + Math.abs(blist[bIndex[1]] - xi);//神社左+寺右
				var pattern4 = Math.abs(alist[aIndex[1]] - xi) * 2 + Math.abs(blist[bIndex[0]] - xi);//神社右+寺左
				var pattern5 = Math.abs(blist[bIndex[0]] - xi) * 2 + Math.abs(alist[aIndex[1]] - xi);//寺左+神社右
				var pattern6 = Math.abs(blist[bIndex[1]] - xi) * 2 + Math.abs(alist[aIndex[0]] - xi);//寺右+神社左
				out.push(pattern1);out.push(pattern2);out.push(pattern3);out.push(pattern4);out.push(pattern5);out.push(pattern6);
				output[i] = Math.min.apply(null, out);
			}
			
		}
	}
	myout(myconv(output, 9));
}
function binarySearch(list,search){
  //listはあらかじめ昇順ソート済みとする。右側が有効エリア、左側が無効エリアと仮定し、
  //searchによって返す要素(インデックス)は ok:有効な部分の最小値、ng:無効な部分の最大値
  var ng = -1;
  var ok = list.length;
  var center;
  while(Math.abs(ok - ng) > 1){
    center = Math.floor((ok + ng) / 2);
    if(list[center] > search){
       ok = center;
    }else{
       ng = center;
    }
  }
  return [ng, ok];
  //return list[ng];
}