原题链接:带配额的文件系统
这道题真的很!!复!!杂!!
真的写不出来。。。。。既然写不出来!那就参考别人的吧:CSP202012-3 带配额的文件系统,这篇是我见过的对这道题讲解的最好的题解了,下面的代码也是根据这篇博客写的,膜拜大佬!
#include <bits/stdc++.h>
using namespace std;
const int N=4e6+10;
#define ll unsigned long long
string path;
ll filesize,ld,lr;
struct Node
{
int father;
map<string,int> child;
int type;
ll ld,lr;
ll fsize;
ll ldsum,lrsum;
}node[4000010];
int num=0;
vector<pair<int,string>> record;
void reback()
{
for(int i=0;i<record.size();i++)
{
int a=record[i].first;
string b=record[i].second;
node[a].child.erase(node[a].child.find(b));
}
}
string func(vector<string> v)
{
int id=0;
int last= v.size()-1>=0 ? v.size()-1:0;
int cur=0;
int pre=num;
string t;
record.clear();
while(cur<last)
{
t=v[cur];
cur++;
if(node[id].child.find(t)==node[id].child.end())
{
num++;
node[id].child[t]=num;
node[num].father=id;
node[num].type=2;
node[num].ld=LLONG_MAX/3;
node[num].lr=LLONG_MAX/3;
record.push_back(make_pair(id,t));
id=num;
}
else
{
int childid=node[id].child[t];
if(node[childid].type==1)
{
num=pre;
reback();
return "N";
}
id=childid;
}
}
if(v.size()>0) t=v[last];
if(node[id].child.find(t)!=node[id].child.end())
{
int childid=node[id].child[t];
if(node[childid].type==2)
{
num=pre;
reback();
return "N";
}
}
ll changesize=0;
if(node[id].child.find(t)==node[id].child.end()) changesize=filesize;
else changesize=-node[node[id].child[t]].fsize+filesize;
if(node[id].ldsum+changesize>node[id].ld)
{
num=pre;
reback();
return "N";
}
cur=id;
while(cur!=-1)
{
if(node[cur].lrsum+changesize>node[cur].lr)
{
num=pre;
reback();
return "N";
}
cur=node[cur].father;
}
if(node[id].child.find(t)==node[id].child.end())
{
num++;
node[num].type=1;
node[num].father=id;
node[num].fsize=filesize;
node[id].child[t]=num;
}
else node[node[id].child[t]].fsize=filesize;
node[id].ldsum+=changesize;
cur=id;
while(cur!=-1)
{
node[cur].lrsum+=changesize;
cur=node[cur].father;
}
return "Y";
}
string funr(vector<string> v)
{
int id=0;
int last= v.size()-1>=0 ? v.size()-1:0;
int cur=0;
int pre=num;
string t;
while(cur<last)
{
t=v[cur];
cur++;
if(node[id].child.find(t)==node[id].child.end()) return "Y";
else
{
int childid=node[id].child[t];
if(node[childid].type==1) return "Y";
id=childid;
}
}
if(v.size()>0) t=v[last];
if(node[id].child.find(t)==node[id].child.end()) return "Y";
ll delsize=0;
int delnode=node[id].child[t];
if(node[delnode].type==1)
{
node[id].ldsum-=node[delnode].fsize;
delsize=node[delnode].fsize;
node[id].child.erase(node[id].child.find(t));
}
else if(node[delnode].type==2)
{
delsize=node[delnode].lrsum;
node[id].child.erase(node[id].child.find(t));
}
cur=id;
while(cur!=-1)
{
node[cur].lrsum-=delsize;
cur=node[cur].father;
}
return "Y";
}
string funq(vector<string> v)
{
if(ld==0) ld=LLONG_MAX/3;
if(lr==0) lr=LLONG_MAX/3;
int id=0;
int cur=0;
int last= v.size()-1>=0 ? v.size()-1:0;
string t;
while(cur<last)
{
t=v[cur];
cur++;
if(node[id].child.find(t)==node[id].child.end()) return "N";
else
{
int childid=node[id].child[t];
if(node[childid].type==1) return "N";
id=childid;
}
}
if(v.size()>0) t=v[last];
int qnode=0;
if(t=="") qnode=0;
else
{
if(node[id].child.find(t)==node[id].child.end()) return "N";
else qnode=node[id].child[t];
}
if(node[qnode].type==1) return "N";
if(ld<node[qnode].ldsum || lr<node[qnode].lrsum) return "N";
node[qnode].ld=ld;
node[qnode].lr=lr;
return "Y";
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n; cin>>n;
char op;
node[0].father=-1;
node[0].type=2;
node[0].ld=LLONG_MAX/3;
node[0].lr=LLONG_MAX/3;
for(int i=1;i<=n;i++)
{
cin>>op>>path;
stringstream ss(path);
string t;
vector<string> v;
while(getline(ss,t,'/')) v.push_back(t);
v.erase(v.begin());
if(op=='C')
{
cin>>filesize;
cout<<func(v)<<endl;
}
else if(op=='R')
{
cout<<funr(v)<<endl;
}
else if(op=='Q')
{
cin>>ld>>lr;
cout<<funq(v)<<endl;
}
}
return 0;
}