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 C++ (judge verdict: WA: Presentation Error)

#include<iostream>
#include<algorithm>
#include<cassert>
#include<stdint.h>
#include<vector>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define all(n) (n).begin(),(n).end()
#define inf (1<<29)
using namespace std;

const uint64_t INF = 100000000000010;

struct List
{
  int identifier;
  uint64_t range[2];// [range[0],range[1]]
  bool hasNext,hasPrev;
  List *prev;
  List *next;
  List(int identifier=inf,uint64_t r1=INF,uint64_t r2=INF):identifier(identifier)
  {
    range[0] = r1, range[1] = r2;
    hasNext = hasPrev = false;
  }
};

int N,I,S,P;
char c;
List list;

void list_walk(List *l)
{
  cout << '[' << l->range[0] << "," << l->range[1] << " : " << l->identifier << "]";
  if(l->hasNext)list_walk(l->next);
}


void ddfs(List *l)
{
  if(l->hasNext)ddfs(l->next);
  if(l->hasPrev)delete l;
    
}

void init()
{
  if(list.hasNext)ddfs(&list);
  list.hasNext = true;
  list.hasPrev = false;
  list.range[0] = list.range[1] = -1;
  list.identifier = -1;
  list.next = new List;
  list.next->hasNext = false;
  list.next->hasPrev = true;
  list.next->range[0] = list.next->range[1] = INF;
  list.next->identifier = inf;
  list.next->prev = &list;
  //cout << "test : " << list.next->prev->identifier << endl;
  //cout << "test : " << list.next->identifier << endl;
}

void dfsW(List *l)
{
  if(!l->hasNext)
    {
      cout << "S = " << S << endl;
      list_walk(&list);
      assert(false);
      return;
    }

  uint64_t v1 = l->range[1];
  uint64_t v2 = l->next->range[0];
  //cout << "v1 = " << v1 << " v2 = " << v2 << endl;
  uint64_t diff = v2-v1-1;
  //cout << "diff = " << diff << endl;
  //assert(diff >= 0);
  if(diff)
    {
      List *node = new List;
      node->identifier = I;
      node->hasNext = node->hasPrev = true;
      node->next = l->next;
      node->prev = l;
      l->next->prev = node;
      l->next = node;

      node->range[0] = v1+1;
      if(S <= diff)
	{
	  node->range[1] = node->range[0] + S - 1;
	  S = 0;
	}
      else if(S > diff)
	{
	  node->range[1] = node->range[0] + diff - 1;
	  S -= diff;
	}
    
    }  

  if(S > 0)dfsW(l->next);
}

void compute_W()
{
  dfsW(&list);
}

void dfsD(List *l)
{
  if(l->identifier == I)
    {
      l->next->prev = l->prev;
      l->prev->next = l->next;
      delete l;
    }
  if(l->hasNext)dfsD(l->next);
}

void compute_D()
{
  dfsD(&list);
}

void dfsR(List *l)
{
  if(l->range[0] <= P && P <= l->range[1])
    {
      cout << l->identifier << endl;
    }
  else
    {
      if(l->hasNext)dfsR(l->next);
      else cout << -1 << endl;
    }
}

void compute_R()
{
  dfsR(&list);
}


int main()
{
  bool f = true;
  while(cin >> N,N)
    {
      if(!f)cout << endl;
      f = false;
      init();
      rep(_,N)
	{
	  cin >> c;
	  if(c == 'W')cin >> I >> S,compute_W();
	  if(c == 'D')cin >> I,compute_D();
	  if(c == 'R')cin >> P,compute_R();
	  //list_walk(&list);cout << endl;
	}
      //list_walk(&list);cout << endl;

    }
  return 0;
}