Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

プログラミングコンテスト II

白虎大学では毎年プログラミングコンテストを開催しています。コンテストは全てのチームの得点が 0の状態から開始し、解答状況に応じて得点が加算されていきます。このコンテストでは、得点の高い順に順位付けが行われます。チームの総数を N としたとき、チームには 1 から N の番号がそれぞれ割り当てられています。得点が同じ場合は番号がより小さい方が上位になります。

白虎大学では、コンテストを盛り上げるために観戦用のランキングシステムを開発しています。開発チームの一員であるあなたは、このシステムの一部であるプログラムの作成を任されています。

与えられた命令に従って、得点の更新と、指定された順位のチームの番号と得点を報告するプログラムを作成せよ。

Input

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

N C
command1
command2
:
commandC

１行目にチーム数 N (2 ≤ N ≤ 100000) と命令の数 C (1 ≤ C ≤ 100000)が与えられる。続く C 行に、１行ずつ命令が与えられる。各命令は以下の形式で与えられる。

0 t p

または

1 m

最初の数字が0のとき更新命令、1のとき報告命令を表す。更新命令では指定された番号 t (1 ≤ t ≤ N) のチームに、整数で与えられる得点 p (1 ≤ p ≤ 109) を加算する。報告命令では指定された順位 m (1 ≤ m ≤ N) のチームの番号と得点を報告する。ただし、報告命令は少なくとも１回現れるものとする。

Output

各報告命令に対して、指定された順位のチームの番号と得点を空白区切りで１行に出力する。

Sample Input 1

3 11
0 2 5
0 1 5
0 3 4
1 1
1 2
1 3
0 3 2
1 1
0 2 1
1 2
1 3

Sample Output 1

1 5
2 5
3 4
3 6
3 6
1 5

Sample Input 2

5 2
1 1
1 2

Sample Output 2

1 0
2 0

Solution in C++14 (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,s,e) for(int (i) = (s);(i) <= (e);(i)++)
#define all(x) x.begin(),x.end()

/* include file*/
#include <functional>
#include <vector>
using namespace std;

template <class Monoid>
struct Segment {
  using Func = function<Monoid(Monoid, Monoid)>;

  vector<Monoid> node;
  Monoid ide;
  int n = 1;

  Func bin_f;
  Func update_f;

  Segment(const vector<Monoid>& init, Monoid ide_, Func f_, Func u_f)
    : bin_f(f_), ide(ide_), update_f(u_f) {
      int sz = init.size();
      while (n < sz) n *= 2;
      node.assign(n * 2 - 1, ide);
      for (int i = 0; i < sz; i++) node[i + n - 1] = init[i];
      for (int i = n - 2; i >= 0; i--)
        node[i] = bin_f(node[i * 2 + 1], node[i * 2 + 2]);
    }

  void update(int i, Monoid x) {
    i += n - 1;
    node[i] = update_f(node[i], x);
    while (i) {
      i = (i - 1) / 2;
      node[i] = bin_f(node[i * 2 + 1], node[i * 2 + 2]);
    }
  }

  Monoid get_inter(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0) r = n;
    if (a <= l && r <= b) return node[k];
    if (r <= a || b <= l) return ide;

    Monoid lm = get_inter(a, b, k * 2 + 1, l, (l + r) / 2);
    Monoid rm = get_inter(a, b, k * 2 + 2, (l + r) / 2, r);
    return bin_f(lm, rm);
  }

};

// http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2730414#1
// http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2730425#1

int com[101010];
i64 t[101010],p[101010],m[101010];
i64 temp[101010];
i64 before[101010];
int main(){
  int N,C;
  cin >> N >> C;
  vector<i64> vec;
  vec.push_back(1e18);
  rep(i,0,N - 1){
    vec.push_back(N - 1 - i);
  }
  rep(i,0,C - 1){
    cin >> com[i];
    if(com[i] == 0){
      cin >> t[i] >> p[i];
      t[i]--;
      temp[t[i]] += p[i];
      vec.push_back(temp[t[i]] * 1100000 + N - 1 - t[i]);
    }
    else{
      cin >> m[i];
    }
  }
  sort(all(vec));
  vec.erase(unique(all(vec)),vec.end());
  int M = vec.size();
  Segment<i64> seg(vector<i64>(M,0),0,[](i64 a,i64 b){return a + b;},[](i64 a,i64 b){return a + b;});
  rep(i,0,N - 1){
    int idx = lower_bound(all(vec),N - 1 - i) - vec.begin();
    seg.update(idx,1);
    temp[i] = 0;
    before[i] = idx;
  }
  vector<int> ans;
  rep(i,0,C - 1){
    if(com[i] == 0){
      i64 T = t[i];
      temp[T] += p[i];
      i64 nxt = (lower_bound(all(vec),temp[T] * 1100000 + N - 1 - t[i]) - vec.begin());
      seg.update(before[T],-1);
      seg.update(nxt,1);
      before[T] = nxt;
    }
    else{
      int ok = -1;
      int ng = seg.n;
      while(ng - ok > 1){
        int mid = (ok + ng) / 2;
        if(seg.get_inter(mid,seg.n) >= m[i]) ok = mid;
        else ng = mid;
      }
      ans.push_back(ok);
    }
  }
  for(int i = 0;i < ans.size();i++){
    cout << N - 1 - (vec[ans[i]] % 1100000) + 1 << " " << vec[ans[i]] / 1100000 << endl;
  }

}