Problem:
Problem D: Restrictive Filesystem

あなたは新型記録媒体の開発チームに所属するプログラマーである．この記録媒体はデータの読み込み及び消去はランダムアクセスが可能である．一方，データを書き込むときは，常に先頭から順番にアクセスしていき，最初に見つかった空き領域にしか書き込むことができない．

あなたはこの記録媒体用のファイルシステムの構築を始めた．このファイルシステムでは，記録媒体の制限から，データは先頭の空き領域から順に書き込まれる．書き込みの途中で別のデータが存在する領域に至った場合は，残りのデータをその後ろの空き領域から書き込んでいく．

データの書き込みはセクタと呼ばれる単位で行われる．セクタには 0 から始まる番号が割り当てられており，この番号は記憶媒体上の物理的な位置を指す．セクタ番号は，記憶媒体の先頭から後方に向かって順に 0，1，2，3，… と割り当てられている．

ファイルシステムには，書き込み，削除，セクタの参照という 3 つのコマンドが存在する．

あなたの仕事はこのファイルシステムの挙動を再現した上で，参照コマンドが実行されたとき対象セクタにはどのファイルが配置されているか出力するプログラムを書くことである．なお，初期状態では記録媒体には何も書き込まれていない．

例えば，Sample Input の最初の例を見てみよう．最初の命令では 0 という識別子を持ったサイズが 2 であるファイルを書き込む．初期状態では記録媒体には何も書き込まれていない，すなわち全てのセクタが空き領域であるから，先頭にある 2 つのセクタ，すなわち 0 番目のセクタと 1 番目のセクタに書き込みが行われる．したがって，書き込みの後の記憶媒体は次のようになっている．

０ ０ 空 空 空 空 空 空 …

2 番目の命令によって，1 という識別子を持つファイルが 2 番目と 3 番目のセクタに書き込まれる．この後の記憶媒体の状態は次のようになる．

０ ０ １ １ 空 空 空 空 …

3 番目の命令によって，0 の識別子を持つファイルが削除される．記憶媒体の状態は次のようになる．

空 空 １ １ 空 空 空 空 …

4 番目の命令によって，2 という識別子を持つファイルを 0 番目，1 番目，4 番目，5 番目のセクタに書き込む．

２ ２ １ １ ２ ２ 空 空 …

最後の命令では，3 番目のセクタが参照される．いま，3 番目のセクタには 1 という識別子のファイルが配置されているので，あなたのプログラムは 1 と出力しなければならない．

Input

入力は複数のデータセットからなる．各データセットは次の形式で与えられる．

N

Command1

Command2

...

CommandN

N は実行されるコマンドの数 (1 ≤ N ≤ 10,000)，Commandi は i 番目に実行されるコマンドをそれぞれ表す．

各コマンドは，コマンド名と 1 つまたは 2 つの引数からなる．コマンド名は 1 つの文字のみからなり，「W」，「D」，「R」のいずれかである．コマンドと引数の間，および引数と引数の間はそれぞれ 1 つのスペースで区切られる．

「W」は書き込みのコマンドを表す．2 つの引数 I (0 ≤ I ≤ 109) と S (1 ≤ S ≤ 109) が与えられる．それぞれ，書き込むファイルの識別子とそのファイルを記憶するのに必要とするセクタの数を示す．

「D」は削除のコマンドを表す．1 つの引数 I (0 ≤ I ≤ 109) が与えられる．削除するファイルの識別子を示す．

「R」は参照のコマンドを表す．1 つの引数 P (0 ≤ P ≤ 109) が与えられる．参照するセクタの番号を示す．

109 よりも大きな番号を持つセクタにはアクセスする必要はないと仮定してよい．また，同じファイル識別子を持つファイルを複数回書き込むことはないことが保証されている．

入力の終わりは，1 つの 0 を含む 1 行で示される．

Output

各データセットについて，参照のコマンドが現れるごとに，そのコマンドによって参照されたファイルの識別子を 1 行に出力せよ．参照したセクタにファイルが書き込まれていなかった場合は，ファイル識別子の代わりに -1 を出力せよ．

各データセットの後には空行を入れること．

Sample Input

6
W 0 2
W 1 2
D 0
W 2 4
R 3
R 1
1
R 1000000000
0

Output for the Sample Input

1
2

-1

Solution in JAVA (judge verdict: Memory Limit Exceeded)

import java.lang.reflect.Array;
import java.util.*;
import java.util.Map.Entry;
import static java.lang.Math.*;
import static java.lang.System.*;

class Main {
	public static Scanner sc = new Scanner(in);
	public static Random rand=new Random();


	static final int INF =1<<30;

	static class Task{
		char key;
		int e1=-1,e2=-1;
		Task(char _key,int _e1,int _e2){
			key=_key;e1=_e1;e2=_e2;
		}
	}

	int N;
	public void run() {
		TCase:while(true){
			N=sc.nextInt();
			if(N==0)return;
			Task[] tasks=new Task[N];

			for(int i=0;i<N;i++){
				char k=sc.next().charAt(0);
				switch(k){
				case 'W':
					tasks[i]=new Task(k,sc.nextInt(),sc.nextInt());
					break;
				case 'D':
					tasks[i]=new Task(k,sc.nextInt(),-1);
					break;
				case 'R':
					tasks[i]=new Task(k,sc.nextInt(),-1);
					break;
				}
			}

			for(int i=0;i<N;i++)if(tasks[i].key=='R'){
				int p=tasks[i].e1+1;
				int e=-1;
				int count=0;
				HashMap<Integer,Integer> hash=new HashMap<Integer, Integer>();
				for(int j=0;j<i;j++){
					switch(tasks[j].key){
					case 'W':
						if(count+tasks[j].e2>=p && e==-1){
							e=tasks[j].e1;
						}
						int v=0;
						if(count+tasks[j].e2>=p)v=count+tasks[j].e2-p;
						else v+=tasks[j].e2;
						if(hash.containsKey(tasks[j].e1)){
							hash.put(tasks[j].e1,hash.get(tasks[j].e1)+v);
						}else{
							hash.put(tasks[j].e1,v);
						}
						count=min(count+tasks[j].e2,p);
						break;
					case 'D':
						if(tasks[j].e1==e)e=-1;
						if(hash.containsKey(tasks[j].e1)){
							Integer c=hash.get(tasks[j].e1);
							count-=c;
							hash.put(tasks[j].e1,0);
						}
						break;
					}
				}
				ln(e);
			}
			ln();
		}
	}

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

	//output lib
	static final String br=System.getProperty("line.separator");
	static final String[] asep=new String[]{""," ",br,br+br};
	static String str(Boolean o){
		return o?"YES":"NO";
	}
//	static String str(Double o){
//		return String.format("%.8f",o);
//	}
	static <K,V> String str(Map<K, V> map){
		StringBuilder sb=new StringBuilder();
		boolean isFirst=true;
		for(Entry<K,V> set:map.entrySet()){
			if(!isFirst)sb.append(br);
			sb.append(str(set.getKey())).append(":").append(str(set.getValue()));
			isFirst=false;
		}
		return sb.toString();
	}
	static <E> String str(Collection<E> list){
		StringBuilder sb=new StringBuilder();
		boolean isFirst=true;
		for(E e:list){
			if(!isFirst)sb.append(" ");
			sb.append(str(e));
			isFirst=false;
		}
		return sb.toString();
	}

	static String str(Object o){
		int depth=_getArrayDepth(o);
		if(depth>0)return _strArray(o,depth);
		Class<?> c=o.getClass();
		if(c.equals(Boolean.class))return str((Boolean)o);
		//if(c.equals(Double.class))return str((Double)o);

		return o.toString();
	}
	static int _getArrayDepth(Object o){
		if(!o.getClass().isArray() || Array.getLength(o)==0) return 0;
		return 	1+_getArrayDepth(Array.get(o,0));
	}
	static String _strArray(Object o,int depth){
		if(depth==0) return str(o);
		StringBuilder sb=new StringBuilder();
		for(int i=0,len=Array.getLength(o);i<len;i++){
			if(i!=0)sb.append(asep[depth]);
			sb.append(_strArray(Array.get(o,i),depth-1));
		}
		return sb.toString();
	}
	static void pr(Object... os){
		boolean isFirst=true;
		for(Object o:os){
			if(!isFirst)out.print(" ");
			out.print(o);
			isFirst=false;
		}
	}
	static void ln(){
		out.println();
	}
	static void ln(Object... os){
		for(Object o:os){
			pr(o);ln();
		}
	}
}