AtCoder problem 070

C++ solution:
#include <bits/stdc++.h>

#include <atcoder/all>

#include <string>



#define rep(i,n) for(int i=0;i < (n);i++)

#define rep2(i, s, n) for (int i = (s); i < (n); i++)

#define rrep(i,n) for(int i=n-1;i>=0;i--)

#define ff first

#define ss second

#define pb push_back

#define ALL(a) (a).begin(),(a).end()



typedef long long ll;



const ll MOD=1000000007ll;

const int MAX=5100000;



using namespace std;

using namespace atcoder;

using mint = modint1000000007;



// aよりもbが大きいならばaをbで更新する

// (更新されたならばtrueを返す)

template <typename T>

bool chmax(T &a, const T& b) {

  if (a < b) {

    a = b;  // aをbで更新

    return true;

  }

  return false;

}

// aよりもbが小さいならばaをbで更新する

// (更新されたならばtrueを返す)

template <typename T>

bool chmin(T &a, const T& b) {

  if (a > b) {

    a = b;  // aをbで更新

    return true;

  }

  return false;

}



ll i,j,k;



int main()

{

	cin.tie(0);	ios::sync_with_stdio(false);

	ll N; cin >> N;

	vector<ll> X(N), Y(N);

	rep(i, N){cin >> X.at(i) >> Y.at(i);}

	sort(ALL(X));

	sort(ALL(Y));



	// xとyで個別に計算

	// x座標の候補：X[0]～X[N-1]のN通り

	ll ansx, ansy, tmpx, tmpy;

	tmpx = 0; tmpy = 0;

	// a=X[0]としたときの不便さを計算

	rep(i, N){tmpx += X[i] - X[0]; tmpy += Y[i] - Y[0];}

	ansx = tmpx; ansy = tmpy;

	// i=1からN-1まで、差分更新しながら計算

	for(i=1; i<N; i++){

		// i以下の座標：不便さがX[i]-X[i-1]増える

		// i+1以上の座標：不便さがX[i]-X[i-1]減る

		tmpx -= (N - i) * (X[i] - X[i-1]);

		tmpx += i * (X[i] - X[i-1]);

		chmin(ansx, tmpx);

		tmpy -= (N - i) * (Y[i] - Y[i-1]);

		tmpy += i * (Y[i] - Y[i-1]);

		chmin(ansy, tmpy);

	}



	cout << ansx + ansy << endl;



  return 0;

}




Python solution: class INPUT:
  def __init__(self):
    self._l=open(0).read().split()
    self._length=len(self._l)
    self._index=0
    return

  def stream(self,k=1,f=int,f2=False):
    assert(-1<k)
    if self._length==self._index or self._length-self._index<k:
      raise Exception("There is no input!")
    elif f!=str:
      if k==0:
        ret=list(map(f,self._l[self._index:]))
        self._index=self._length
        return ret
      if k==1 and not f2:
        ret=f(self._l[self._index])
        self._index+=1
        return ret
      if k==1 and f2:
        ret=[f(self._l[self._index])]
        self._index+=1
        return ret
      ret=[]
      for _ in [0]*k:
        ret.append(f(self._l[self._index]))
        self._index+=1
      return ret
    else:
      if k==0:
        ret=list(self._l[self._index:])
        self._index=self._length
        return ret
      if k==1 and not f2:
        ret=self._l[self._index]
        self._index+=1
        return ret
      if k==1 and f2:
        ret=[self._l[self._index]]
        self._index+=1
        return ret
      ret=[]
      for _ in [0]*k:
        ret.append(self._l[self._index])
        self._index+=1
      return ret
pin=INPUT().stream

"""
pin(number[default:1],f[default:int],f2[default:False])
if number==0 -> return left all
listを変数で受け取るとき、必ずlistをTrueにすること。
"""

def main():
  N=pin(1)
  X=[]
  Y=[]
  for _ in[0]*N:
    x,y=pin(2)
    X.append(x)
    Y.append(y)
  X.sort()
  Y.sort()
  ac=-10**9-10
  wa=10**9+10
  #3分探索
  ansx=float("inf")
  searchX=lambda c:sum(abs(c-i)for i in X)
  for _ in[0]*100:
    #print(ac,wa)
    midx1=(2*ac+wa)//3
    midx2=(ac+2*wa)//3
    d1=searchX(midx1)
    d2=searchX(midx2)
    if d1<d2:
      wa=midx2
    else:
      ac=midx1
  ansx=ac
  if searchX(ac)>searchX(wa):
    ansx=wa
  if searchX(wa)>searchX((ac+wa)//2):
    ansx=(wa+ac)//2
  #print(ansx)
  ac=-10**9-10
  wa=10**+10
  searchY=lambda c:sum(abs(c-i)for i in Y)
  for _ in[0]*100:
    #print(ac,wa)
    midy1=(2*ac+wa)//3
    midy2=(ac+2*wa)//3
    d1=searchY(midy1)
    d2=searchY(midy2)
    if d1<d2:
      wa=midy2
    else:
      ac=midy1
  ansy=ac
  if searchY(ac)>searchY(wa):
    ansy=wa
  if searchY(wa)>searchY((ac+wa)//2):
    ansy=(wa+ac)//2
  #print(ansy)
  print(searchX(ansx)+searchY(ansy))
  return

main()