注意点:
1:先判断,再操作
2:可能文件已经存在,先算出需要的文件配额,再创建
3:开 long long
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
//普通文件
struct FNode
{
ll File_size;
string name;
FNode(ll fsize,string name):File_size(fsize),name(name){};
};
//目录
struct LNode
{
ll File_LD;//目录配额
ll File_LR;//后代配额
ll R_File_LD;//已经使用的目录配额
ll R_File_LR;//已经使用的后代配额
string name;
vector<LNode> R_file;//目录下的目录文件
vector<FNode> D_file;//目录下的普通文件
LNode(ll size1,ll size2,string name):File_LD(size1),File_LR(size2),name(name)
{R_File_LD = 0;R_File_LR = 0;}
LNode(string name)
{
File_LD = File_LR = 0;
this->name = name;
R_File_LD = 0;
R_File_LR = 0;
}
} Root(0,0,"/");
//分割路径
vector<string> split_path(string s)
{
vector<string> res;
res.push_back("/");
string temp_path;
for(ll i = 1;i<=s.size();++i)
{
if(i == s.size() && temp_path.size())
{
res.push_back(temp_path);
break;
}
if(s[i] == '/')
{
res.push_back(temp_path);
temp_path.clear();
}
else temp_path += s[i];
}
return res;
}
//确定要创建文件占用配额的真实大小
ll is_C_size(const vector<string> & path_name,ll file_size)
{
LNode *temp = &Root;
ll path_lens = path_name.size();
for(ll i = 1;i < path_lens; ++ i)
{
//最后一个目录
if(i == path_lens - 1)
{
for(ll j = 0;j < temp->D_file.size();++ j)//如果文件已经存在,重新计算需要的配额大小
if(path_name[i] == temp->D_file[j].name)return file_size - temp->D_file[j].File_size;
}
else//前面的目录
{
ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();
for(j = 0;j < Rlens;++j)
if(path_name[i] == (*temp).R_file[j].name)
{
temp = &(temp->R_file[j]);
break;
}
if(j == Rlens)
return file_size;
}
}
return file_size;
}
//判断是否能创建
bool is_C(const vector<string> & path_name,ll file_size)
{
file_size = is_C_size(path_name,file_size);
LNode *temp = &Root;
ll path_lens = path_name.size();
for(ll i = 1;i < path_lens; ++ i)
{
if(i == path_lens - 1)
{
if(temp->File_LD)//目录配额
if(temp->R_File_LD + file_size > temp->File_LD)
return false;
if(temp->File_LR)//后代配额
if(temp->R_File_LR + file_size > temp->File_LR)
return false;
for(ll j = 0;j < temp->R_file.size();++ j)//已经存在同名目录
if(path_name[i] == temp->R_file[j].name)return false;
}
else
{
ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();
for(j = 0;j < Dlens;++j)//已经存在同名文件
if(path_name[i] == temp->D_file[j].name)return false;
if(temp->File_LR)//后代配额
if(temp->R_File_LR + file_size > temp->File_LR)
return false;
for(j = 0;j < Rlens;++j)
if(path_name[i] == (*temp).R_file[j].name)//目录存在
{
temp = &(temp->R_file[j]);
break;
}
if(j == Rlens)//目录不存在
{
return true;
}
}
}
return true;
}
//C
void C_oper()
{
string path;
cin>>path;
ll file_size;
scanf("%lld",&file_size);
vector<string> path_name = split_path(path);//解析路径
if(!is_C(path_name,file_size))
{
printf("N\n");
return ;
}
LNode *temp = &Root;
ll the_file_size = file_size;
file_size = is_C_size(path_name,file_size);
ll path_lens = path_name.size();
for(ll i = 1;i < path_lens; ++ i)
{
if(i == path_lens - 1)
{
ll j = 0,Dlens = temp->D_file.size();
//cout<<"the size of D_file is "<<Dlens<<endl;
for(j = 0;j < Dlens;++ j)
{
if(path_name[i] == temp->D_file[j].name)//文件已经存在,直接修改大小
{
//cout << "find " << path_name[i]<< " seccessful!"<<endl;
temp->D_file[j].File_size = the_file_size;
break;
}
}
if(j == Dlens)//文件不存在,创建
{
temp->D_file.push_back(FNode(the_file_size,path_name[i]));
//cout << "create " << path_name[i]<< " seccessful!"<<endl;
}
//修改配额
temp->R_File_LD += file_size;
temp->R_File_LR += file_size;
}
else
{
ll j = 0,Rlens = (*temp).R_file.size();
temp->R_File_LR += file_size;
for(j = 0;j < Rlens;++j)
if(path_name[i] == (*temp).R_file[j].name)//目录存在
{
//cout<<"Find "<<path_name[i]<<endl;
temp = &(temp->R_file[j]);
break;
}
if(j == Rlens)//目录不存在
{
//cout<<"Create "<<path_name[i]<<endl;
temp->R_file.push_back(LNode(path_name[i]));
temp = &(temp->R_file[j]);
}
}
}
printf("Y\n");
}
//返回的first为删除的是文件1还是者目录2,或者都不存在0,second为收回的配额大小
pair<ll,ll> is_R_size(const vector<string> & path_name )
{
LNode *temp = &Root;
ll path_lens = path_name.size();
for(ll i = 1;i < path_lens; ++ i)
{
if(i == path_lens - 1)
{
for(ll j = 0;j < temp->D_file.size();++ j)//删除的是文件
if(path_name[i] == temp->D_file[j].name)return make_pair(1,temp->D_file[j].File_size);
for(ll j = 0;j < temp->R_file.size();++ j)//删除的是目录
if(path_name[i] == temp->R_file[j].name)return make_pair(2, temp->R_file[j].R_File_LR);
}
else
{
ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();
for(j = 0;j < Rlens;++j)
if(path_name[i] == (*temp).R_file[j].name)
{
temp = &(temp->R_file[j]);
break;
}
if(j == Rlens)//上级目录不存在
return make_pair(0,-1);
}
}
return make_pair(0,-1);
}
//R
void R_oper()
{
string path;
cin>>path;
vector<string> path_name = split_path(path);
auto R_size = is_R_size(path_name);
printf("Y\n");
if(R_size.first == 0)
return ;
LNode *temp = &Root;
ll path_lens = path_name.size();
ll file_type = R_size.first,file_size = R_size.second;
for(ll i = 1;i < path_lens; ++ i)
{
if(i == path_lens - 1)
{
temp->R_File_LR -= file_size;//收回后代配额
if(file_type == 1)
{
ll j = 0;
for(j = 0;j < temp->D_file.size();++ j)
if(path_name[i] == temp->D_file[j].name)
break;
temp->D_file.erase(temp->D_file.begin() + j);//删除文件
temp->R_File_LD -= file_size;//收回目录配额
}
else
{
ll j = 0;
for(j = 0;j < temp->R_file.size();++ j)
if(path_name[i] == temp->R_file[j].name)
break;
temp->R_file.erase(temp->R_file.begin() + j);//删除目录
}
}
else
{
ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();
temp->R_File_LR -= file_size;
for(j = 0;j < Rlens;++j)
if(path_name[i] == (*temp).R_file[j].name)
{
temp = &(temp->R_file[j]);
break;
}
}
}
}
//是否能够更新配额
bool is_Q_size(const vector<string> & path_name,ll file_lr,ll file_ld)
{
LNode *temp = &Root;
ll path_lens = path_name.size();
//更新/目录
if(path_lens == 1)
{
if(!file_lr && !file_ld)
return true;
if(!file_lr)
{
if(file_ld >= temp->R_File_LD)return true;
else return false;
}
if(!file_ld)
{
if(file_lr >= temp->R_File_LR)return true;
else return false;
}
if(file_lr >= temp->R_File_LR && file_ld >= temp->R_File_LD)
return true;
else return false;
}
//更新/目录下的目录
for(ll i = 1;i < path_lens; ++ i)
{
ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();
for(j = 0;j < Rlens;++j)
if(path_name[i] == (*temp).R_file[j].name)
{
temp = &(temp->R_file[j]);
break;
}
if(j == Rlens)//目录不存在
return false;
if(i == path_lens - 1)
{
//判断是否满足配额
if(!file_lr && !file_ld)
return true;
if(!file_lr)
{
if(file_ld >= temp->R_File_LD)return true;
else return false;
}
if(!file_ld)
{
if(file_lr >= temp->R_File_LR)return true;
else return false;
}
if(file_lr >= temp->R_File_LR && file_ld >= temp->R_File_LD)
return true;
else return false;
}
}
return false;
}
//Q
void Q_oper()
{
string path;
cin>>path;
ll file_rd,file_ld;
scanf("%lld%lld",&file_ld,&file_rd);
vector<string> path_name = split_path(path);
if(!is_Q_size(path_name,file_rd,file_ld))
{
printf("N\n");
return ;
}
LNode *temp = &Root;
ll path_lens = path_name.size();
if(path_lens == 1)//修改/目录配额
{
temp->File_LR = file_rd;
temp->File_LD = file_ld;
}
for(ll i = 1;i < path_lens; ++ i)
{
ll j = 0,Rlens = (*temp).R_file.size(),Dlens = (*temp).D_file.size();
for(j = 0;j < Rlens;++j)
if(path_name[i] == (*temp).R_file[j].name)
{
temp = &(temp->R_file[j]);
break;
}
if(i == path_lens - 1)//修改配额
{
temp->File_LR = file_rd;
temp->File_LD = file_ld;
}
}
printf("Y\n");
}
//打印所有文件
void output(LNode * root)
{
ll Rlens = root->R_file.size(),Dlens = root->D_file.size();
cout<<root->name<<"\n";
cout<<"----------"<<root->name<<" LD: "<<root->File_LD<<" "<<root->R_File_LD<<"-----------\n";
for(ll i = 0;i < Dlens;++ i)
cout<<root->D_file[i].name<<":"<<root->D_file[i].File_size<<" ";
cout<<endl;
cout<<"----------"<<root->name<<" LR "<<root->File_LR<<" "<<root->R_File_LR<<"-----------\n";
for(ll i = 0;i < Rlens;++i)
{
output(&(root->R_file[i]));
}
}
int main()
{
ll t;
scanf("%lld",&t);
//output(&Root);
while(t -- )
{
string oper;
cin>>oper;
if(oper[0] == 'C')
C_oper();
else if(oper[0] == 'R')
R_oper();
else if(oper[0] == 'Q')
Q_oper();
//output(&Root);
}
return 0;
}