Problem:
ワカサギ釣り大会 2

桧原湖でワカサギ釣り大会が行われました。今回はキャッチ＆リリースが推奨されているようです。

参加者番号と釣った匹数またはリリースした匹数を１つのイベントとして順番に読み込み、各イベントの直後に最も多くのワカサギを手元に獲得している参加者番号と匹数を出力するプログラムを作成してください。最も多く獲得している参加者が複数いる場合（あるいは全ての参加者が 0 匹の場合）は、その中で参加者番号が最も小さい一人を出力してください。

入力

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

n q
a1 v1
a2 v2
:
aq vq

n (1 ≤ n ≤ 1000000) は参加者の数、q (1 ≤ q ≤ 100000)はイベントの数を表す。ai (1 ≤ ai ≤ n)   vi ( -100 ≤ vi ≤ 100) は、i 番目のイベントで参加者 ai が vi 匹獲得あるいはリリースしたことを示す。vi は正の値が獲得、負の値がリリースを示し、0 が与えられることはない。

出力

各イベントごとに、最も多くのワカサギを手元に獲得している参加者の参加者番号と匹数を１つの空白区切りで１行に出力する。

入力例1

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

出力例1

1 4
2 5
1 7
1 7
2 12

入力例2

3 5
1 4
2 5
2 -3
3 4
1 -1

出力例2

1 4
2 5
1 4
1 4
3 4

Solution in Ruby (judge verdict: Accepted)

class Fisherman
  attr_accessor :id, :num;
  def initialize(id, num)
    @id = id
    @num = num
  end
  def >(other)
    if self.num == other.num && self.id > other.id
        return true
    elsif self.num > other.num
      return true
    end
    return false
  end
  def <(other)
    if self.num == other.num && self.id < other.id
        return true
    elsif self.num < other.num
      return true
    end
    return false
  end
end

q = gets.split.map(&:to_i)[1]

h = [] # heap
id = {} #
pos = {}

q.times{|i|
  a, v = gets.split.map(&:to_i)
  if id[a]
    pp = pos[a]
    id[a] += v
    h[pp].num += v
    if v > 0
      cc = pp
      pp = (cc+1)/2-1
      b = h[pp].id
      while cc > 0 && h[pp] < h[cc]
        h[pp], h[cc] = h[cc], h[pp]
        pos[a], pos[b] = pos[b], pos[a]
        cc = pp
        pp = (cc+1)/2-1
        b = h[pp].id
      end
    else
      loop do
        maxid = pp
        l = 2*pp+1
        maxid = l if h[l] && h[l] > h[maxid]
        r = 2*pp+2
        maxid = r if h[r] && h[r] > h[maxid]
        break if maxid == pp
        c = h[pp].id
        b = h[maxid].id
        h[maxid], h[pp] = h[pp], h[maxid]
        pos[c], pos[b] = pos[b], pos[c]
        pp = maxid
      end
    end
  else
    h << Fisherman.new(a, v)
    cc = h.size - 1
    pos[a] = cc
    pp = (cc+1)/2-1
    b = h[pp].id
    while cc > 0 && h[pp] < h[cc]
      h[pp], h[cc] = h[cc], h[pp]
      pos[a], pos[b] = pos[b], pos[a]
      cc = pp
      pp = (cc+1)/2-1
      b = h[pp].id
    end
    id[a] = v
  end
  mval = h[0].num
  mid = h[0].id

  queue = [0]
  pp = 0
  while queue.size > 0
    pp = queue.shift
    mid = h[pp].id if mid > h[pp].id
    l = 2*pp+1
    queue << l if h[l] && h[l].num == mval
    r = 2*pp+2
    queue << r if h[r] && h[r].num == mval
  end
  puts [mid, mval].join(" ")
}