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)

#include <stdio.h>
#include <stdlib.h>

typedef struct {
	int id;
	int fishNum;
} player_t;

int playerComp(player_t x,player_t y) {
	if(x.fishNum>y.fishNum)return 1;
	if(x.fishNum<y.fishNum)return -1;
	if(x.id<y.id)return 1;
	if(x.id>y.id)return -1;
	return 0;
}

typedef struct RedBlackTreeNode_tag {
	player_t key;
	int isRed;
	struct RedBlackTreeNode_tag* left;
	struct RedBlackTreeNode_tag* right;
} RedBlackTreeNode;

RedBlackTreeNode* root=NULL;

#define RBT_REQUEST_NONE			0
#define RBT_REQUEST_INIT			1
#define RBT_REQUEST_NEXTOFLEFT		2
#define RBT_REQUEST_NEXTOFRIGHT		3
#define RBT_REQUEST_ROTATE_LEFT		0x100
#define RBT_REQUEST_ROTATE_RIGHT	0x200

#define RBT_REQUEST_DEL_INIT		1

RedBlackTreeNode* RedBlackTreeNode_new(player_t key) {
	RedBlackTreeNode* ret=malloc(sizeof(RedBlackTreeNode));
	if(ret==NULL)exit(1);
	ret->key=key;
	ret->isRed=1;
	ret->left=ret->right=NULL;
	return ret;
}

void RedBlackTreeNode_delete(RedBlackTreeNode* node) {
	if(node->left)RedBlackTreeNode_delete(node->left);
	if(node->right)RedBlackTreeNode_delete(node->right);
	free(node);
}

void RedBlackTree_rotate(RedBlackTreeNode** target,int isLeft) {
	if(isLeft && (*target)->right!=NULL) {
		RedBlackTreeNode* top=*target;
		RedBlackTreeNode* topRight=(*target)->right;
		RedBlackTreeNode* topRightLeft=(*target)->right->left;
		(*target)->right->left=top;
		(*target)->right=topRightLeft;
		*target=topRight;
	} else if((*target)->left!=NULL) {
		RedBlackTreeNode* top=*target;
		RedBlackTreeNode* topLeft=(*target)->left;
		RedBlackTreeNode* topLeftRight=(*target)->left->right;
		(*target)->left->right=top;
		(*target)->left=topLeftRight;
		*target=topLeft;
	}
}

int RedBlackTree_insertInternal(RedBlackTreeNode** now,player_t key) {
	int ret=RBT_REQUEST_NONE;
	int isLeft;
	if(*now==NULL) {
		*now=RedBlackTreeNode_new(key);
		return RBT_REQUEST_INIT;
	} else if(playerComp((*now)->key,key)==0) {
		return RBT_REQUEST_NONE;
	} else if(playerComp((*now)->key,key)<0) {
		ret=RedBlackTree_insertInternal(&((*now)->right),key);
		isLeft=0;
	} else { /* key<(*now)->key */
		ret=RedBlackTree_insertInternal(&((*now)->left),key);
		isLeft=1;
	}

	if(ret==RBT_REQUEST_INIT) {
		/* case 1 */
		if((*now)->isRed) {
			ret=isLeft?RBT_REQUEST_NEXTOFLEFT:RBT_REQUEST_NEXTOFRIGHT;
		} else {
			ret=RBT_REQUEST_NONE;
		}
	} else if(ret==RBT_REQUEST_NEXTOFLEFT) {
		if(isLeft) {
			if((*now)->right==NULL || !(*now)->right->isRed) {
				/* case 4 */
				(*now)->isRed=1;
				(*now)->left->isRed=0;
				RedBlackTree_rotate(now,0);
				ret=RBT_REQUEST_NONE;
			} else {
				/* case 2 */
				(*now)->left->isRed=0;
				if((*now)->right)(*now)->right->isRed=0;
				(*now)->isRed=1;
				ret=RBT_REQUEST_INIT;
			}
		} else {
			if((*now)->left==NULL || !(*now)->left->isRed) {
				/* case 3 */
				RedBlackTree_rotate(&((*now)->right),0);
				/* case 4 */
				(*now)->isRed=1;
				(*now)->right->isRed=0;
				RedBlackTree_rotate(now,1);
				ret=RBT_REQUEST_NONE;
			} else {
				/* case 2 */
				(*now)->right->isRed=0;
				if((*now)->left)(*now)->left->isRed=0;
				(*now)->isRed=1;
				ret=RBT_REQUEST_INIT;
			}
		}
	} else if(ret==RBT_REQUEST_NEXTOFRIGHT) {
		if(isLeft) {
			if((*now)->right==NULL || !(*now)->right->isRed) {
				/* case 3 */
				RedBlackTree_rotate(&((*now)->left),1);
				/* case 4 */
				(*now)->isRed=1;
				(*now)->left->isRed=0;
				RedBlackTree_rotate(now,0);
				ret=RBT_REQUEST_NONE;
			} else {
				/* case 2 */
				(*now)->left->isRed=0;
				if((*now)->right)(*now)->right->isRed=0;
				(*now)->isRed=1;
				ret=RBT_REQUEST_INIT;
			}
		} else {
			if((*now)->left==NULL || !(*now)->left->isRed) {
				/* case 4 */
				(*now)->isRed=1;
				(*now)->right->isRed=0;
				RedBlackTree_rotate(now,1);
				ret=RBT_REQUEST_NONE;
			} else {
				/* case 2 */
				(*now)->right->isRed=0;
				if((*now)->left)(*now)->left->isRed=0;
				(*now)->isRed=1;
				ret=RBT_REQUEST_INIT;
			}
		}
	}
	return ret;
}

void RedBlackTree_insert(player_t key) {
	RedBlackTree_insertInternal(&root,key);
	root->isRed=0;
}

RedBlackTreeNode* RedBlackTree_searchPtr(RedBlackTreeNode* now,player_t key) {
	if(now==NULL)return NULL;
	if(playerComp(now->key,key)==0)return now;
	return RedBlackTree_searchPtr(playerComp(now->key,key)<0?now->right:now->left,key);
}

RedBlackTreeNode* RedBlackTree_searchMinNode(RedBlackTreeNode* now) {
	if(now->left==NULL)return now;
	return RedBlackTree_searchMinNode(now->left);
}

RedBlackTreeNode* RedBlackTree_searchMaxNode(RedBlackTreeNode* now) {
	if(now->right==NULL)return now;
	return RedBlackTree_searchMaxNode(now->right);
}

int RedBlackTree_removeInternal(RedBlackTreeNode** now,RedBlackTreeNode* target) {
	int ret=RBT_REQUEST_NONE;
	int isLeft=0;
	int colorTemp;
	if(*now==NULL)return RBT_REQUEST_NONE;
	if(*now==target) {
		RedBlackTreeNode* delNode=*now;
		int delNodeIsRed=delNode->isRed;
		*now=(*now)->left?(*now)->left:(*now)->right;
		delNode->left=delNode->right=NULL;
		RedBlackTreeNode_delete(delNode);
		/* case 0 */
		if(delNodeIsRed) {
			return RBT_REQUEST_NONE;
		} else if(*now && (*now)->isRed) {
			(*now)->isRed=0;
			return RBT_REQUEST_NONE;
		}
		return RBT_REQUEST_DEL_INIT;
	} else if(playerComp((*now)->key,target->key)<=0) {
		ret=RedBlackTree_removeInternal(&((*now)->right),target);
		isLeft=0;
	} else {
		ret=RedBlackTree_removeInternal(&((*now)->left),target);
		isLeft=1;
	}
	if(ret==RBT_REQUEST_DEL_INIT) {
		if(isLeft) {
			if((*now)->right!=NULL && (*now)->right->isRed) {
				/* case 2 */
				(*now)->isRed=!(*now)->isRed;
				(*now)->right->isRed=!(*now)->right->isRed;
				RedBlackTree_rotate(now,1);
				now=&((*now)->left);
			}
			ret=RBT_REQUEST_NONE;
			if((*now)->right!=NULL) {
				if(((*now)->right->left==NULL ||
						!((*now)->right->left->isRed)) &&
						((*now)->right->right==NULL ||
						!((*now)->right->right->isRed))) {
					if((*now)->isRed) {
						/* case 4 */
						(*now)->isRed=0;
						(*now)->right->isRed=1;
					} else {
						/* case 3 */
						(*now)->right->isRed=1;
						ret=RBT_REQUEST_INIT;
					}
				} else if((*now)->right->right!=NULL &&
						(*now)->right->right->isRed) {
					/* case 6 */
					colorTemp=(*now)->isRed;
					(*now)->isRed=(*now)->right->isRed;
					(*now)->right->isRed=colorTemp;
					(*now)->right->right->isRed=0;
					RedBlackTree_rotate(now,1); 
				} else {
					/* case 5 */
					(*now)->right->isRed=1; 
					(*now)->right->left->isRed=0;
					RedBlackTree_rotate(&((*now)->right),0);
					/* case 6 */
					colorTemp=(*now)->isRed;
					(*now)->isRed=(*now)->right->isRed;
					(*now)->right->isRed=colorTemp;
					(*now)->right->right->isRed=0;
					RedBlackTree_rotate(now,1); 
				}
			}
		} else {
			if((*now)->left!=NULL && (*now)->left->isRed) {
				/* case 2 */
				(*now)->isRed=!(*now)->isRed;
				(*now)->left->isRed=!(*now)->left->isRed;
				RedBlackTree_rotate(now,0);
				now=&((*now)->right);
			}
			ret=RBT_REQUEST_NONE;
			if((*now)->left!=NULL) {
				if(((*now)->left->left==NULL ||
						!((*now)->left->left->isRed)) &&
						((*now)->left->right==NULL ||
						!((*now)->left->right->isRed))) {
					if((*now)->isRed) {
						/* case 4 */
						(*now)->isRed=0;
						(*now)->left->isRed=1;
					} else {
						/* case 3 */
						(*now)->left->isRed=1;
						ret=RBT_REQUEST_INIT;
					}
				} else if((*now)->left->left!=NULL &&
						(*now)->left->left->isRed) {
					/* case 6 */
					colorTemp=(*now)->isRed;
					(*now)->isRed=(*now)->left->isRed;
					(*now)->left->isRed=colorTemp;
					(*now)->left->left->isRed=0;
					RedBlackTree_rotate(now,0);
				} else {
					/* case 5 */
					(*now)->left->isRed=1; 
					(*now)->left->right->isRed=0;
					RedBlackTree_rotate(&((*now)->left),1);
					/* case 6 */
					colorTemp=(*now)->isRed;
					(*now)->isRed=(*now)->left->isRed;
					(*now)->left->isRed=colorTemp;
					(*now)->left->left->isRed=0;
					RedBlackTree_rotate(now,0); 
				}
			}
		}
	}
	return ret;
}

int RedBlackTree_remove(player_t key) {
	RedBlackTreeNode* target;
	target=RedBlackTree_searchPtr(root,key);
	if(target==NULL)return 0;
	if(target->left!=NULL && target->right!=NULL) {
		RedBlackTreeNode* minNode;
		minNode=RedBlackTree_searchMinNode(target->right);
		target->key=minNode->key;
		target=minNode;
	}
	RedBlackTree_removeInternal(&root,target);
	return 1;
}

player_t RedBlackTree_getMax(void) {
	player_t nothing={1,0};
	RedBlackTreeNode* max=RedBlackTree_searchMaxNode(root);
	return max==NULL?nothing:max->key;
}

int player_num[1000001];

int main(void) {
	int n,q;
	int i;
	int a,v;
	player_t playerBuffer;
	scanf("%d%d",&n,&q);
	for(i=0;i<q;i++) {
		scanf("%d%d",&a,&v);
		playerBuffer.id=a;
		playerBuffer.fishNum=player_num[a];
		RedBlackTree_remove(playerBuffer);
		playerBuffer.fishNum+=v;
		player_num[a]=playerBuffer.fishNum;
		RedBlackTree_insert(playerBuffer);
		playerBuffer=RedBlackTree_getMax();
		if(playerBuffer.fishNum==0)playerBuffer.id=1;
		printf("%d %d\n",playerBuffer.id,playerBuffer.fishNum);
	}
	return 0;
}