这道题目是对文件系统的模拟。
第一步,选取“静态树”作为本题的数据结构。
第二步,设计结点信息。需要包括 ①孩子结点信息 ② 目录配额与后代配额的最大值 ③ 当前目录配额与后代配额 ④ 父节点信息 ⑤ 区分普通文件与目录 ⑥ 若是普通文件,则需记录文件大小。
第三步,设计创建普通文件模块。
第四步,删除文件模块。
第五步,设置配额值。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 4e6+5;
typedef long long ll;
struct Node{
map<string, int> child;
ll max_ld1, max_ld2;
ll ld1, ld2;
ll fsize;
int flag;
int fa_id;
};
Node node[maxn];
int n, index = 0; // index 记录当前操作结点
vector< pair<int, string> > reback; // 记录输入的路径
void Reback() // 按照输入的路径清除树上的结点
{
for(int i = 0; i < reback.size(); i++)
{
int f_id = reback[i].first;
string son_name = reback[i].second;
node[f_id].child.erase(son_name);
}
}
string Cdo()
{
int id = 0;
int tindex = index; // 记录开始的编号,销毁路径前恢复到 index
string path; ll fsize;
int p = 1;
cin>>path>>fsize;
int last = path.rfind("/");
reback.clear();
// 第一步:路径检查
while(p < last)
{
string t = "";
for(;p < last && path[p] != '/'; p++)
{
t += path[p];
}
p++;
if(node[id].child.find(t) == node[id].child.end())
{ // 没找到,则创建路径
node[id].child[t] = ++index;
node[index].fa_id = id;
node[index].flag = 2;
node[index].max_ld1 = LLONG_MAX / 3;
node[index].max_ld2 = LLONG_MAX / 3;
node[index].ld1 = 0;
node[index].ld2 = 0;
reback.push_back(make_pair(id, t));
id = index;
}else{ // 找到路径,进行判断
int sonid = node[id].child[t];
if(node[sonid].flag == 1)
{ index = tindex;
Reback();
return "N";
}
id = sonid;
}
}
// 第二步:文件检查
string f_name = path.substr(last + 1);
if(node[id].child.find(f_name) != node[id].child.end())
{
int sonid = node[id].child[f_name];
if(node[sonid].flag == 2)
{
index = tindex;
Reback();
return "N";
}
}
ll py;
if(node[id].child.find(f_name) == node[id].child.end()) py = fsize;
else py = fsize - node[node[id].child[f_name]].fsize;
// 检查目录配额
if(node[id].ld1 + py > node[id].max_ld1)
{
index = tindex;
Reback();
return "N";
}
// 检查所有祖先结点的后代配额
int temp_id = id;
while(temp_id != -1)
{
if(node[temp_id].ld2 + py > node[temp_id].max_ld2)
{
index = tindex;
Reback();
return "N";
}
temp_id = node[temp_id].fa_id;
}
if(node[id].child.find(f_name) == node[id].child.end())
{ // 配额够用的情况下,创建新的文件
node[id].child[f_name] = ++index;
node[index].fa_id = id;
node[index].flag = 1;
node[index].fsize = fsize;
} else{
// 配额够用的情况下,替换原有的文件
int sonid = node[id].child[f_name];
node[sonid].fsize = fsize;
}
node[id].ld1 += py;
int temp_id2 = id;
while(temp_id2 != -1)
{
node[temp_id2].ld2 += py;
temp_id2 = node[temp_id2].fa_id;
}
return "Y";
}
string Rdo()
{
string path;
cin>>path;
int last = path.rfind("/");
int p = 1;
int id = 0;
// 第一步: 路径检查
while(p < last)
{
string t = "";
for(; p < last && path[p] != '/'; p++)
{
t += path[p];
}
p++;
if(node[id].child.find(t) == node[id].child.end()) return "Y";
else{
int sonid = node[id].child[t];
if(node[sonid].flag == 1) return "Y";
id = sonid;
}
}
// 第二步: 文件删除
string f_name = path.substr(last + 1);
if(node[id].child.find(f_name) == node[id].child.end()) return "Y";
else{
int sonid = node[id].child[f_name];
if(node[sonid].flag == 1)
{ // 是普通文件
node[id].child .erase(f_name);
node[id].ld1 -= node[sonid].fsize;
int temp_id = id;
while(temp_id != -1)
{
node[temp_id].ld2 -= node[sonid].fsize;
temp_id = node[temp_id].fa_id;
}
}else{ // 是目录
node[id].child.erase(f_name);
int temp_id = id;
while(temp_id != -1)
{
node[temp_id].ld2 -= node[sonid].ld2;
temp_id = node[temp_id].fa_id;
}
}
}
return "Y";
}
string Qdo()
{
string path;
ll set_ld1, set_ld2;
cin>>path>>set_ld1>>set_ld2;
if(set_ld1 == 0) set_ld1 = LLONG_MAX / 3;
if(set_ld2 == 0) set_ld2 = LLONG_MAX / 3;
int last = path.rfind("/");
int p = 1;
int id = 0;
while(p < last)
{
string t = "";
for(;p < last && path[p] != '/'; p++)
{
t += path[p];
}
p++;
if(node[id].child.find(t) == node[id].child.end()) return "N"; // 路径不存在
else{
int sonid = node[id].child[t];
if(node[sonid].flag == 1) return "N"; // 路径错误
id = sonid;
}
}
string f_name = path.substr(last + 1);
int qnode;
if(id == 0) qnode = 0; // 根目录
else{
if(node[id].child.find(f_name) == node[id].child.end()) return "N";
else qnode = node[id].child[f_name];
}
if(node[qnode].flag == 1) return "N"; // 是普通文件
else{ // 是目录
if(set_ld1 < node[qnode].ld1 || set_ld2 < node[qnode].ld2) return "N";
else{
node[qnode].max_ld1 = set_ld1;
node[qnode].max_ld2 = set_ld2;
return "Y";
}
}
}
int main()
{
// 根目录
node[0].fa_id = -1;
node[0].flag = 2;
node[0].max_ld1 = LLONG_MAX / 3;
node[0].max_ld2 = LLONG_MAX / 3;
node[0].ld1 = 0;
node[0].ld2 = 0;
char c;
string str;
cin>>n;
for(int i = 0; i < n; i++)
{
cin>>c;
if(c == 'C')
{
cout<<Cdo()<<endl;
}
if(c == 'R')
{
cout<<Rdo()<<endl;
}
if(c == 'Q')
{
cout<<Qdo()<<endl;
}
}
return 0;
}