#P2262. [HNOI2004] FTP服务器

[HNOI2004] FTP服务器

题目背景

File Transfer Protocol,文件传输协议,简称 FTP。人们可以通过FTP实现资源共享。一般的情况下用户访问一个 FTP 服务器是通过类似资源管理器的形式对该服务器上的资源进行浏览,并且不同权限的用户可以实现下载文件/文件夹,上传文件/文件夹。

题目描述

一个FTP服务器的所有资源都以文件的形式按树形结构存储在不同的文件夹里,最低一级的是根目录(即根文件夹),根目录里有若干个文件和文件夹,每一个文件夹里都可以拥有 00 个或多个文件及文件夹,同一文件夹里不存在名称相同的文件和文件夹。

一个用户包含三个属性:

  • userType\text{userType}:用户类型;
  • userState\text{userState}:用户状态(用户正在执行的操作);
  • userPosition\text{userPosition}:用户当前所处的位置(即用户正在浏览的文件夹)。

用户分 33 种类型:上传用户 uploadUser\text{uploadUser},下载用户 downloadUser\text{downloadUser},匿名用户 guest\text{guest}

操作分 33 种类型:浏览 scan\text{scan},下载 download\text{download},上传 upload\text{upload}

用户的权限是指用户允许进行的操作。不同类型的用户的权限是不同的。

任何一个用户是不能进行其没有权限的操作的,例如:一个匿名用户想要下载一个文件或者文件夹是不允许的。

一个文件/文件夹包含三个属性:

  • fileName/folderName\text{fileName/folderName}:文件名(不包含空格和回车);
  • fileSize/folderSize\text{fileSize/folderSize}:文件大小 (单位 byte\text{byte}0<filesize<1050 <\mathrm{filesize}< 10^50<folderSize<1080<\mathrm{folderSize}< 10^8,文件夹的大小是它里面所包含的所有文件大小的总和);
  • fileState/folderState\text{fileState/folderState}:当前状态,当前状态有两种:
    • 一种为正常 normal\text{normal}(文件/文件夹为正常状态时,允许用户对其进行操作);
    • 另一种为上传未完成 uploading\text{uploading}(处在此种状态时,用户之能够对其进行浏览操作,如果一个文件夹中有一个或多个文件处于 uploading\text{uploading} 状态,那么这个文件夹也处于 uploading\text{uploading} 状态)。

一个 FTP 服务器除了它所拥有的文件资源外,还有如下属性:

  1. 访问用户的最大数量(包括所有不同类型的用户) maxUserNumber<100\text{maxUserNumber}<100。如果当前访问用户数量已经达到最大值的话,其他新的用户对服务器的访问将是失败的。
  2. 服务器的最大流量 maxServerFlux<107\text{maxServerFlux}<10^7
  3. 单个用户允许的最大下载/上传流量 maxUserFlux\text{maxUserFlux}

FTP 服务器运行的最小时间单位为秒。

每一个用户在同一时刻只能进行一种操作。用户下载和上传文件/文件夹是需要一定时间的,而这个时间决定于用户流量 userFlux\text{userFlux},单位为 byte/second\text{byte/second},注意如果某一时刻文件/文件夹仍须上传/下载的大小(>0>0)小于 userFlux\text{userFlux} 的话,上传/下载时间仍将按照一秒钟看待。

userFlux\text{userFlux} 的值是如何确定的呢?

$$\mathrm{userFlux} = \min(\mathrm{presentMaxUserFlux},\mathrm{maxUserFlux}) $$

其中,presentMaxUserFlux\text{presentMaxUserFlux} 为当前服务器的单个用户最大流量:

$$\mathrm{presentMaxUserFlux} = \lfloor \mathrm{maxServerFlux} / \mathrm{userTotal}\rfloor $$

userTotal\text{userTotal} 表示该时刻的正在进行上传和下载操作的用户数量)

一个用户通过一系列命令实现其在 FTP 服务器上的相关操作。下面介绍这些命令:

connect\verb!connect! 命令

  • 格式:[name] + 空格 + connect + 空格 + 参数A\verb![name] + 空格 + connect + 空格 + 参数A!
  • 例:tsinghua connect 1\verb!tsinghua connect 1!
  • 表示在名叫 name\verb!name! 的用户请求以 A\verb!A! 身份连接到服务器上。如果当前的最大使用用户还没达到 maxUserNumber\text{maxUserNumber},并且该用户未连接到服务器,则连接成功,服务器反馈回一个相关信息 success\verb!success!。否则反馈信息为 unsuccess\verb!unsuccess!。一旦连接成功,用户其所处的位置 userPosition\text{userPosition} 为服务器的根目录。A=1A=1 表示上传用户,A=2A=2 下载表示用户,A=3A=3 表示匿名用户。

quit\verb!quit! 命令

  • 格式:[name] + 空格 + quit\verb![name] + 空格 + quit!
  • 例:tsinghua quit\verb!tsinghua quit!
  • 表示名叫 name\verb!name! 的用户断开与服务器的连接。如果用户未连接反馈 unsuccess\verb!unsuccess!,否则反馈 success\verb!success!。(注意用户在任何状态下都可以断开与服务器的连接)。

cd\verb!cd! 命令

  • 格式:[name] + 空格 + cd + 空格 + [folderName/文件夹名称]\verb![name] + 空格 + cd + 空格 + [folderName/文件夹名称]!
  • 例:THU cd FD\verb!THU cd FD!
  • 表示名叫 name\verb!name! 的用户希望从当前所处的文件夹进入该文件夹中的一个名叫 folderName\text{folderName} 的文件夹。如果名叫 folderName\text{folderName} 的文件夹存在并且处于 normal\text{normal} 状态,则改变用户当前所处位置 userPosition\text{userPosition},反馈相关信息 success\verb!success!,如果该文件夹不存在或该用户没有成功连接,则反馈信息为 unsuccess\verb!unsuccess!

cd..\verb!cd..! 命令

  • 格式:[name] + 空格 + cd..\verb![name] + 空格 + cd..!
  • 例:9# cd..\verb!9# cd..!
  • 表示名叫 name\verb!name! 的用户希望从当前所处的文件夹返回到他的上一级文件夹。如果用户处于根目录或者用户未连接,则命令执行失败返回 unsuccess\verb!unsuccess!,否则返回 success\verb!success!,并且改变用户所处位置 userPosition\text{userPosition}

download\verb!download! 命令

  • 格式:[name] + 空格 + download + 空格 + [name1]\verb![name] + 空格 + download + 空格 + [name1]!
  • 例:A download 1.txt\verb!A download 1.txt!
  • 表示名叫 name\verb!name! 的用户希望从当前所处文件夹下载名为 name1\verb!name1! 的文件或者文件夹。如果用户未连接,用户没有下载权限,名为 name1\verb!name1! 的文件/文件夹不存在,或者该文件/文件夹处于 uploading\text{uploading} 状态时,反馈信息 unsuccess\verb!unsuccess!,否则返回 success\verb!success! 并且开始下载该文件/文件夹。(一旦一个下载命令开始执行,那么执行该命令的用户所下载的是下载命令执行的那一时刻的那一个文件/文件夹,也就是说如果一个用户正在下在某个文件夹,在下载过程中,有另外一用户在这个文件夹里面上传文件,那么原下载用户是不可能下载到这个新上传的文件的)。

upload\verb!upload! 命令

  • 格式:$\verb![name] + 空格 + upload + 空格 + [name1] + 空格 + [size]!$。
  • 例:A upload B 1\verb!A upload B 1!
  • 表示名叫 name\verb!name! 的用户希望在当前所处的文件夹上传一个名叫 name1\verb!name1! 的大小为 size\text{size} 的文件/文件夹。注意:
    • 用户通过 upload\verb!upload! 命令上传文件夹只能为空文件夹,当 size=0\text{size}=0 表示上传文件夹,size>0表示上传文件。
    • 如果当前目录已经存在了同名的文件/文件夹,用户未成功连接或者用户没有上传权限,反馈信息 unsuccess\verb!unsuccess!,否则反馈 success\verb!success!,并且开始上传文件/文件夹。(如果一个用户想要上传一个非空文件夹,是很容易通过一系列 upload\verb!upload! 以及 cd\verb!cd! 命令实现的)。

除上传文件和下载文件/文件夹命令需要耗时外,其他的命令都不需要执行时间。

你的任务是模拟一个 FTP 服务器在某一时间段内的运行过程。

输入格式

一开始你将从文件中获得 FTP 的服务器的初始信息。第一行为 33 个正整数,分别表示 $\text{maxUserNumber},\text{maxServerFlux},\text{maxUserFlux}$。接下来的若干行描述 server\text{server} 里已有文件资源的存储情况。

第一行总是描述的根目录中的一个文件或者文件夹。

如果某一行描述的是一个文件或者文件夹那么该行的数据为 name + 空格 + size\verb!name + 空格 + size!,如果 size=0\text{size}=0 表示这是一个文件夹,否则表示一个大小为 size\text{size} 的文件。

如果某一行描述的是一个文件夹,那么接下来的若干行描述的都是这个文件夹里的内容,直到一个与之对应的减号为止。这些数据都是递归描述的。因为一开始就是描述整个根目录里的文件和文件夹,所以文件信息的最后一行也为减号。(参看输入示例)。

下面的每一行为 time + 空格 + order\verb!time + 空格 + order! 的形式给出,例如 4 ares connect 1\verb!4 ares connect 1! 表示:在服务器开启后 44 秒钟,名叫 ares\verb!ares! 的用户请求以 uploadUser\text{uploadUser} 的身份连接到服务器上来。

输入的最后一行为一个字符串 down\verb!down!

所有输入命令的时刻 time\text{time} 都以命令出现的先后递增,同一时刻的命令以输入中出现的先后顺序确定其执行顺序。

输出格式

请你将每一条命令的反馈信息输出。

5 200 200
unzip.exe 100
xxxx 50
bin 0
tpx.exe 200
turbo.exe 300
tpx.tp 400
temp 0
-
-
readme.txt 100
-
0 ares connect 2
0 ares download zip.exe
1 ares download bin
5 ares download xxxx
6 ares cd bin
6 ares connect 1
6 ares quit
7 ares connect 1
7 rosen connect 2
7 ares cd bin
8 ares upload A 300
9 rosen download bin
10 rosen download bin
down

success
unsuccess
success
unsuccess
success
unsuccess
success
success
success
success
success
unsuccess
success

提示

来源:HNOI2004 经过修改。