题目
题意
模拟一个文件系统,要求此文件系统实现目录功能,创建文件功能,删除文件功能,以及对子树的文件大小之和配置限额。
思路
大模拟,注意到文件系统树的高度小于20,那么可以记录每个节点的父亲节点,暴力往上跳修改每个结点的子树的文件大小和。注意开long long,注意在创建文件失败时产生的目录要回溯删除掉。
我好像从来没有写过这种正经的大模拟题,写了两个半小时才满分。。。
/* Author : Rshs */
#include<bits/stdc++.h>
using namespace std;
#define FI first
#define SE second
#define LL long long
#define LDB long double
#define MP make_pair
#define PII pair<int,int>
#define SZ(a) (int)a.size()
#define DB1(a) cerr<<(#a)<<'='<<a<<endl
#define DB2(a,b) cerr<<(#a)<<'='<<a<<' '<<(#b)<<'='<<b<<endl
#define DB3(a,b,c) cerr<<(#a)<<'='<<a<<' '<<(#b)<<'='<<b<<' '<<(#c)<<'='<<c<<endl
const LDB pai = acos(-1.0L);
const LDB eps = 1e-10;
const LL mod = 1e9+7;
const int MXN =4e6+5;
inline int Add(int x,int y){return (x+=y)>=mod?x-mod:x;}
inline int Sub(int x,int y){return (x-=y)<0?x+mod:x;}
inline int Mul(int x,int y) {return 1LL*x*y%mod;}
inline int Pow(int x,LL y){int res=1;while(y){if(y&1)res=1LL*res*x%mod;x=1LL*x*x%mod;y>>=1;}return res;}
struct node{
map<string,int>son;
int kind; // 1文件, 2目录
LL ld,lr;
LL sld,slr;
LL fsize;
int fa;
}g[MXN];
int clockIndex=0;
vector<pair<int,string> >reback;
void REBACK(){
for(int i=0;i<SZ(reback);i++){
int a=reback[i].FI;
string b=reback[i].SE;
g[a].son.erase(g[a].son.find(b));
}
}
string Cdo(){
string path;cin>>path;
LL fsize;scanf("%lld",&fsize);
int p=1,id=0,Lpath=path.length(),last=-1;
for(int i=Lpath-1;i>=0;i--){
if(path[i]=='/') {last=i;break;}
}
/*********************/
int tclock=clockIndex;
reback.clear();
while(p<last){
string t="";
while(p<last&&path[p]!='/'){
t=t+path[p];p++;
}
p++;
if(g[id].son.find(t)==g[id].son.end()){
g[id].son[t]=++clockIndex;
g[clockIndex].fa=id; g[clockIndex].kind=2;
g[clockIndex].ld=LLONG_MAX/3;g[clockIndex].lr=LLONG_MAX/3;
reback.push_back(MP(id,t));
id=clockIndex;
}
else {
int sonid=g[id].son[t];
if(g[sonid].kind==1) {clockIndex=tclock;REBACK();return "N";}
id=sonid;
}
}
string t="";
for(int i=last+1;i<Lpath;i++) t=t+path[i];
if(g[id].son.find(t)!=g[id].son.end()){
int sonid=g[id].son[t];
if(g[sonid].kind==2) {clockIndex=tclock;REBACK();return "N";}
}
/*********************/
LL py=0;
if(g[id].son.find(t)==g[id].son.end()) py=fsize;
else py=-g[g[id].son[t]].fsize+fsize;
if(g[id].sld+py>g[id].ld) {clockIndex=tclock;REBACK();return "N";}
int now=id;
while(now!=-1){
if(g[now].slr+py>g[now].lr) {clockIndex=tclock;REBACK();return "N";}
now=g[now].fa;
}
/*********************/
if(g[id].son.find(t)==g[id].son.end()) {
g[++clockIndex].kind=1;g[clockIndex].fsize=fsize;
g[clockIndex].fa=id;g[id].son[t]=clockIndex;
}
else g[g[id].son[t]].fsize=fsize;
g[id].sld+=py;
while(id!=-1){
g[id].slr+=py;
id=g[id].fa;
}
return "Y";
}
string Rdo(){
string path;cin>>path;
int p=1,id=0,Lpath=path.length(),last=-1;
for(int i=Lpath-1;i>=0;i--){
if(path[i]=='/') {last=i;break;}
}
while(p<last){
string t="";
while(p<last&&path[p]!='/'){
t=t+path[p];p++;
}
p++;
if(g[id].son.find(t)==g[id].son.end()){
return "Y";
}
else {
int sonid=g[id].son[t];
if(g[sonid].kind==1) return "Y";
id=sonid;
}
}
string t="";
for(int i=last+1;i<Lpath;i++) t=t+path[i];
if(g[id].son.find(t)==g[id].son.end()){
return "Y";
}
int delNode=g[id].son[t];
LL add=0;
if(g[delNode].kind==1){
g[id].sld-=g[delNode].fsize;
add=g[delNode].fsize;
g[id].son.erase(g[id].son.find(t));
}
if(g[delNode].kind==2){
add=g[delNode].slr;
g[id].son.erase(g[id].son.find(t));
}
while(id!=-1){
g[id].slr-=add;
id=g[id].fa;
}
return "Y";
}
string Qdo(){
string path;cin>>path;
LL LD,LR;scanf("%lld%lld",&LD,&LR);
if(LD==0) LD=LLONG_MAX/3;
if(LR==0) LR=LLONG_MAX/3;
int p=1,id=0,Lpath=path.length(),last=-1;
for(int i=Lpath-1;i>=0;i--){
if(path[i]=='/') {last=i;break;}
}
while(p<last){
string t="";
while(p<last&&path[p]!='/'){
t=t+path[p];p++;
}
p++;
if(g[id].son.find(t)==g[id].son.end()){
return "N";
}
else {
int sonid=g[id].son[t];
if(g[sonid].kind==1) return "N";
id=sonid;
}
}
string t="";
for(int i=last+1;i<Lpath;i++) t=t+path[i];
int qNode;
if(t=="") {
qNode=0;
}
else {
if(g[id].son.find(t)==g[id].son.end()) return "N";
else qNode=g[id].son[t];
}
if(g[qNode].kind==1) return "N";
if(LD<g[qNode].sld||LR<g[qNode].slr) return "N";
g[qNode].ld=LD;g[qNode].lr=LR;
return "Y";
}
int main(){
g[0].kind=2;g[0].ld=LLONG_MAX/3;g[0].lr=LLONG_MAX/3;g[0].fa=-1;
int q;cin>>q;
while(q--){
char op;cin>>op;
if(op=='C'){
cout<<Cdo()<<'\n';
}
if(op=='R'){
cout<<Rdo()<<'\n';
}
if(op=='Q'){
cout<<Qdo()<<'\n';
}
}
return 0;
}