Problem:
Score : 600 points

Problem Statement

There is a function f(x), which is initially a constant function f(x) = 0.

We will ask you to process Q queries in order. There are two kinds of queries, update queries and evaluation queries, as follows:

An update query 1 a b: Given two integers a and b, let g(x) = f(x) + |x - a| + b and replace f(x) with g(x).

An evaluation query 2: Print x that minimizes f(x), and the minimum value of f(x). If there are multiple such values of x, choose the minimum such value.

We can show that the values to be output in an evaluation query are always integers, so we ask you to print those values as integers without decimal points.

Constraints

All values in input are integers.

1 \leq Q \leq 2 \times 10^5

-10^9 \leq a, b \leq 10^9

The first query is an update query.

Input

Input is given from Standard Input in the following format:

Q
Query_1
:
Query_Q

See Sample Input 1 for an example.

Output

For each evaluation query, print a line containing the response, in the order in which the queries are given.

The response to each evaluation query should be the minimum value of x that minimizes f(x), and the minimum value of f(x), in this order, with space in between.

Sample Input 1

4
1 4 2
2
1 1 -8
2

Sample Output 1

4 2
1 -3

In the first evaluation query, f(x) = |x - 4| + 2, which attains the minimum value of 2 at x = 4.

In the second evaluation query, f(x) = |x - 1| + |x - 4| - 6, which attains the minimum value of -3 when 1 \leq x \leq 4. Among the multiple values of x that minimize f(x), we ask you to print the minimum, that is, 1.

Sample Input 2

4
1 -1000000000 1000000000
1 -1000000000 1000000000
1 -1000000000 1000000000
2

Sample Output 2

-1000000000 3000000000

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
#include <stdio.h>

using namespace std;
#define inputInt(a) int a; cin >> a; 
#define inputInt2(a,b) int a; int b; cin >> a >> b; 
#define inputInt3(a,b,c) int a; int b; int c; cin >> a >> b >> c;
#define inputLong(a) long a;cin >> a; 
#define inputIntArray(a,N) int a[N];for(int i=0;i<N;i++){cin >> a[i];}
#define inputLongArray(a,N) long a[N];for(int i=0;i<N;i++){cin >> a[i];}
#define inputIntArray2(a,b,N) int a[N]; int b[N]; for(int i=0;i<N;i++){cin >> a[i] >> b[i];}
#define output(answer) cout << answer << endl;
#define fN(i,N)    for(int i=0; i<N; i++)
#define fSE(i,s,e) for(int i=s; i<=e; i++)
#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const ll MOD2 = 998244353;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }

//BIT
class BinaryIndexedTree{
  int N;
  vector<int> BIT;
  
  public:  
  
  BinaryIndexedTree(int n):BIT(n+1,0){ N = n; }//1-indexed
  BinaryIndexedTree(vector<int> v):BIT(v.size()+1,0){
    N = v.size();
    for(int i=1; i<=N; i++){
      add(i,v[i-1]); 
    }
  }
  
  void add(int x, int y){//0-indexed originから呼び出される時
    for(int i=x+1; i <= N; i += i&-i){
      BIT[i] += y;
    }
  }
  
  int sum(int x){
    int ret = 0;
    for(int i=x+1; i>0; i -= i&-i){
      ret += BIT[i];
    }
    return ret;
  }
  
  int getXth(int x){
    //最小値を求める時
    int ok = N+1;//解が存在する最大値
    int ng = -1;//解が存在しない最小値
    /*
    //最大値を求める時
    ll ok = -1;//解が存在する最小値
    ll ng = 1e18;//解が存在しない最大値
    */
          
    while(abs(ok-ng) > 1){
      int mid = (ok+ng)/2;
      if((this->sum(mid)) >= x){//((C+1)+1)/2
        ok = mid; 
      }else{
        ng = mid;
      }
    } 
    return ok;
  }

  inline int operator [] (int index) const{//読み取り
     return BIT[index];
  }
  inline int& operator [] (int index){//書き取り
     return BIT[index];
  }
};

//座標圧縮
class CC{
  public:
  vector<ll> v;//元々のvector
  map<ll,int> mp;//0-indexed
  bool isUnique = true;
  
  CC(vector<ll> v){//座標圧縮が必要になるのはlonglongintの時が多い？
    sort(v.begin(),v.end());
    auto result = unique(v.begin(),v.end());
    isUnique = (result == v.end());
    v.erase(result, v.end());//重複を除いてもmapから参照できる。
    this->v = v;
    
    for(int i=0; i<v.size(); i++){
      mp.emplace_hint(mp.end(),v[i],i);
    }
  }
  
  ll getKey(int value){//keyが必要な場合は座標圧縮前のベクトルから参照できるため、これは不要？
    //座標圧縮後valueに対応するkeyを取得→0-indexedの時value+1番目のkey→v[value]で良いのでは？
    //key0がvalue0に対応している点に注意。
    //return next(mp.begin(), value)->first; 
    return this->v[value];
  }
  

  /*
  inline int operator [] (ll index) const{//読み取り
     if(mp.find(index) != mp.end()) return mp[index];
     else{ return -1;}
  }
  */
};

int main()
{
  //方針
  //クエリ1:aはBITに追加。bは和をとる。
  //クエリ2:aの個数の偶奇で場合分け。中央値に対して新しく追加されたaの大小で場合分け。
  //cin.tie(0);
  //ios::sync_with_stdio(false);
  
  //input
  //クエリ
  int Q; scanf("%d", &Q);
  vector<ll> vt(2e5,0), va(2e5,0), vb(2e5,0);
  ll sum_a = 0, sum_b = 0;
  
  int T, a, b;
  int c = 0;
  for(int i=0; i<Q; i++){
    scanf("%d", &T); vt[i] = T;
    if(T == 1){
      scanf("%d %d", &a, &b);
      va[c] = a; vb[c] = b;
      c ++;
    }else{
      continue; 
    }
  }

  //main
  CC cc(va);//まず座標圧縮
  
  //aの個数を管理。
  BinaryIndexedTree bit(va.size());//Qが上界。
  ll center = 0;
  
  int count = 0;
  
  for(int i=0; i<Q; i++){
    if(vt[i]==1){//クエリ1
      bit.add(cc.mp[va[count]],1); 
      sum_b += vb[count];
    
      if(count == 0){
        center = va[count];
      }else if((count+1)%2){//aが偶数から奇数になる。
        if(va[count]<=center){//左側
          //center = center;
          sum_a += abs(va[count]-center);
        }else{//右側
          center = cc.getKey(bit.getXth(count/2+1));
          sum_a += abs(va[count]-center);
        }
      }else{//aが奇数から偶数になる。
        if(va[count]>=center){//右側
          //center = center;
          sum_a += abs(va[count]-center);
        }else{//左側
          int x = cc.getKey(bit.getXth((count+1)/2));
          ll g = abs(center-x);
          center = x;
          sum_a += (abs(va[count]-center) + g);
        }
      }
      count ++;
    }else{//クエリ2
      printf("%lld %lld\n", center, sum_a+sum_b);
    }
  }
  
  // output
  //cout << cc.getKey(2) << endl;
  //cout << sum_b << endl;
  return 0;
}