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 JAVA (judge verdict: Wrong Answer)

import java.util.*;
import java.io.*;

public class Main {
	class Total {
		int id, total;
		public Total(int id, int total){
			this.id = id;
			this.total = total;
		}
		public void add(int x){
			total += x;
		}
	}
	class PriorityQueue {
		Total[] heap;
		int size;
		int[] idx;
		public PriorityQueue(int n){
			heap = new Total[n];
			size = n;
			idx = new int[n];
			for(int i = 0; i < n; i++){
				heap[i] = new Total(i+1, 0);
				idx[i] = i;
			}
		}
		public void addValue(int a, int x){
			heap[idx[a]].total += x;
			if( x > 0 ){
				heapify_up(idx[a]);
			} else {
				heapify_down(idx[a]);
			}
		}
		public void swap(int x, int y){
			Total temp = new Total(heap[x].id, heap[x].total);
			heap[x] = heap[y];
			heap[y] = temp;
			int tmp = idx[x];
			idx[x] = idx[y];
			idx[y] = tmp;
		}
		public int compare(Total x, Total y){
			if( x.total > y.total ){
				return -1;
			}
			if( x.total == y.total && x.id < y.id ){
				return -1;
			}
			return 1;
		}
		public void heapify_up(int a){
			int par = (a-1)/2;
			if( compare(heap[a], heap[par]) < 0 ){
				swap(a, par);
				heapify_up(par);
			}
		}
		public void heapify_down(int a){
			int ch1 = 2*a+1;
			int ch2 = 2*a+2;
			int max = a;
			if( ch1 < size && compare(heap[ch1], heap[max]) < 0 ){
				max = ch1;
			}
			if( ch2 < size && compare(heap[ch2], heap[max]) < 0 ){
				max = ch2;
			}
			if( max != a ){
				swap(a, max);
				heapify_down(max);
			}
		}
	}
	public void solve() throws IOException {
		int n = nextInt();
		PriorityQueue queue = new PriorityQueue(n);
		int q = nextInt();
		for(int i = 0; i < q; i++){
			int a = nextInt();
			int v = nextInt();
			queue.addValue(a-1, v);	
			writer.println(queue.heap[0].id + " " + queue.heap[0].total);
		}			
	}

	public static void main(String[] args) throws IOException {
		new Main().run();
	}

	BufferedReader reader;
	StringTokenizer tokenizer;
	PrintWriter writer;

	public void run() throws IOException {
		try {
			reader = new BufferedReader(new InputStreamReader(System.in));
			tokenizer = null;
			writer = new PrintWriter(System.out);
			solve();
			reader.close();
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String nextToken() throws IOException {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	public int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}
}