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: Runtime Error)

/*
AizuOnline A2152
Title Restricted File SYSTEM
RE
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct bd //block descriptor
{
        int start;
        int size;
        struct bd * nextp;
} *bds;
struct bd * emptyblock;
struct bd * free_block;  // start ptr
struct fd //file descriptor
{
        int name;
        struct bd * b;
} *fds;
struct fd * last_fdp;

int N;
char read_buf[30];
struct mcb
{
        int name;
        int start;
        int end;
} *mcbs;
int mcbcnt;
//
void memalloc()
{
        bds= malloc(sizeof(struct bd)*10001);
        fds= malloc(sizeof(struct fd)*10001);
        mcbs=malloc(sizeof(struct mcb)*10001);
}
void dump_sector_memory()
{
        struct fd *fdp;
        struct bd *bdp;
        int cnt;

        cnt=0;
        bdp=free_block;
        do
        {     
                mcbs[cnt].name = -1;
                mcbs[cnt].start=bdp->start;
                mcbs[cnt].end  =bdp->start+bdp->size-1;
                cnt++;
                bdp=bdp->nextp;
        }
        while(bdp);

        for(fdp=&fds[0];fdp<last_fdp;fdp++)
        {
                bdp=fdp->b;
                
                while(bdp)
                {
                        mcbs[cnt].name = fdp->name;
                        mcbs[cnt].start=bdp->start;
                        mcbs[cnt].end  =bdp->start+bdp->size-1;
                        cnt++;
                        bdp=bdp->nextp;
                }
        }
        mcbcnt = cnt;
}

void dump_sector()
{
        struct fd *fdp;
        struct bd *bdp;
     

        printf("------------\n");
        bdp=free_block;
        do
        {       printf("Free block:");
                printf("%d ~ %d\n",bdp->start,bdp->start+bdp->size-1);
                bdp=bdp->nextp;
        }
        while(bdp);

        for(fdp=&fds[0];fdp<last_fdp;fdp++)
        {
                bdp=fdp->b;
                
                //if(bdp)
                        while(bdp)
                {
                        printf("File:%d:",fdp->name);
                        printf("%d ~ %d\n",bdp->start,bdp->start+bdp->size-1);
                        bdp=bdp->nextp;
                }
                
                
        }
}
void copy_block(struct bd *src,struct bd *dst)
{
        memcpy(dst,src,sizeof(struct bd));
}

void write_command(int fname,int fsize)
{
        struct bd *bp,**bpp,*nextbp;
        struct fd *filep;
        int oldsize;


        
        filep=last_fdp++;
        filep->name=fname;

        bpp=&(filep->b);
                        
        while(1)
        {
                *bpp=free_block;
                bp = free_block;
                //printf("FSZ %d\n",fsize);
                        
                if(fsize <= bp->size)   //
                {
                        nextbp=bp->nextp;
                        bp->nextp = NULL;
                        oldsize   = bp->size;
                        bp->size  = fsize;

                        if(fsize < oldsize)   //split
                        {
                                copy_block(bp,emptyblock);
                                free_block=emptyblock++;
                                free_block->start = bp ->start +fsize;
                                free_block->size  = oldsize    -fsize;
                                free_block->nextp = nextbp;
                                return;
                        }
                        else //just size
                        {
                                free_block=nextbp;
                                break;
                        }
                }
                else 
                {
                        free_block=bp->nextp;     
                        fsize -= bp->size;
                        if(fsize > 0)
                        {
                                bpp=&(bp->nextp);
                                continue;
                        }
                        return;
                }
        }
}
int compare_mcb(const void *x, const void *y)
{
        return ((struct mcb *)x)->start - ((struct mcb *)y)->start;
}

int read_command(int sector)
{
        int center,mini,maxi;

        dump_sector_memory();
        qsort(mcbs,mcbcnt,sizeof(struct mcb),compare_mcb);
        mini=0;maxi=mcbcnt;
        while(maxi-mini>1)
        {
                center=(maxi+mini)/2;
#ifdef DEBUG
                printf("R:%d C:%d %d\n",sector,
                       mcbs[center].start,mcbs[center].end);
#endif
                if(mcbs[center].start > sector)
                {
                        maxi=(maxi+mini)/2;
                }
                else if(mcbs[center].end < sector)
                {
                        mini=(maxi+mini)/2;
                }
                else  //equal
                {
                        return(mcbs[center].name);
                }
        }
        if(maxi-mini==1)
        {
                if(mcbs[maxi].start < sector)
                        return(mcbs[maxi].name);
                else
                        return(mcbs[mini].name);
        }
        return(mcbs[center].name);
}
void release_block(struct bd * r_bdp)
{
        struct bd *bdp,*next_bdp,*prev_bdp;

        bdp=free_block;
LOOP:
        if(bdp->start > r_bdp->start)
        {
                if(bdp==free_block)
                {
                        next_bdp  = free_block;
                        free_block = r_bdp;
                        r_bdp->nextp = next_bdp;
                }
                else  // 2nd block iko
                {
                        next_bdp = bdp;
                        prev_bdp->nextp = r_bdp;
                        r_bdp->nextp = next_bdp;
                }
                return;
        }

        prev_bdp=bdp;
        if((bdp=bdp->nextp))
                goto LOOP;
        else  // last block
        {
                prev_bdp->nextp=r_bdp;
                r_bdp->nextp=NULL;
        }
}
void delete_command(int fname)
{
        struct fd *fdp;
        struct bd *bdp,*nextbdp;

        for(fdp=fds;fdp<last_fdp;fdp++)
                if(fdp->name==fname)
                        goto NEXT;
        return;
NEXT:

        bdp=fdp->b;

        while(bdp)
        {
                nextbdp=bdp->nextp;
                release_block(bdp);
                bdp = nextbdp;
        }
        fdp->b=NULL;
}
void dispatch(char * buf)
{
        char *p;
        int  op1,op2,ret;

        p=strtok(buf," ");
        if(p[0]=='W')
        {
                p=strtok(NULL," ");
                sscanf(p,"%d",&op1);
                p=strtok(NULL," ");
                sscanf(p,"%d",&op2);
                write_command(op1,op2);
                return;
        }
        if(p[0]=='D')
        {
                p=strtok(NULL," ");
                sscanf(p,"%d",&op1);
                delete_command(op1);
                return;
        }
        if(p[0]=='R')
        {
                p=strtok(NULL," ");
                sscanf(p,"%d",&op1);
                ret=read_command(op1);
#ifdef DEBUG
                printf("ANS=");
#endif
                printf("%d\n",ret);
                return;
        }
}
void init()
{
        memalloc();

        bds[0].start=0;
        bds[0].size=1000000000;
        bds[0].nextp=NULL;
        free_block = &bds[0];

        last_fdp = &fds[0];
        emptyblock=&bds[1];
}
int main()
{
        int i;
        char * ret;

        init();

        while(EOF!=scanf("%d ",&N) && N)
        {
                for(i=0;i<N;i++)
                {
                        memset(read_buf,30,'\0');
                        ret=fgets(read_buf,30,stdin);
                        dispatch(read_buf);
#ifdef DEBUG
                        if(read_buf[0] != 'R')
                                dump_sector();
#endif
                }
                printf("\n");        
        }

        return(0);
}