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 C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    struct Player : IComparable
    {
        internal int id, stok;

        public int CompareTo(object obj)
        {
            Player other = (Player)obj;

            if (stok == other.stok)
            {
                return other.id - id;
            }
            return stok - other.stok;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            StringBuilder sb = new StringBuilder();

            string[] input = Console.ReadLine().Split(' ');
            int q = int.Parse(input[1]);

            PriorityQueue<Player> pq = new PriorityQueue<Player>();
            int[] memo = new int[1000001];

            for (int i = 0; i < q; i++)
            {
                input = Console.ReadLine().Split(' ');
                int a = int.Parse(input[0]);
                int v = int.Parse(input[1]);

                memo[a] += v;

                Player temp;
                temp.id = a;
                temp.stok = memo[a];

                pq.Enqueue(temp);

                while (true)
                {
                    temp = pq.Peek();

                    if (memo[temp.id] != temp.stok)
                    {
                        pq.Dequeue();
                    }
                    else
                    {
                        sb.AppendLine(temp.id + " " + temp.stok);
                        break;
                    }
                }
            }
            Console.Write(sb);
        }
    }

    class PriorityQueue<T> where T : IComparable
    {
        List<T> heap;
        int size;

        public PriorityQueue()
        {
            heap = new List<T>();
        }

        public void Enqueue(T x)
        {
            heap.Add(x);
            int i = size++;

            while (i > 0)
            {
                int p = (i - 1) / 2;

                if (Compare(heap[p], x) <= 0) break;

                heap[i] = heap[p];
                i = p;
            }
            heap[i] = x;
        }

        public T Dequeue()
        {
            T ret = heap[0];
            T x = heap[--size];

            int i = 0;
            while (i * 2 + 1 < size)
            {
                int a = i * 2 + 1;
                int b = i * 2 + 2;

                if (b < size && Compare(heap[b], heap[a]) < 0)
                    a = b;
                if (Compare(heap[a], x) >= 0)
                    break;

                heap[i] = heap[a];
                i = a;
            }
            heap[i] = x;
            heap.RemoveAt(size);
            return ret;
        }

        public T Peek()
        {
            return heap[0];
        }

        public int Count()
        {
            return size;
        }

        private int Compare(T x, T y)
        {
            return y.CompareTo(x);
        }
    }
}