CCF-202012-3-带配额的文件系统

题意:
给你n条指令,三种操作。1.创建普通文件。2.删除普通文件后目录。3.给目录设置配额。判断每条指令是否执行成功
题解:
将数据以树的形式存储下来,在创建普通文件时,注意祖先节点的配额是否超出。
代码如下:

#include<bits/stdc++.h>  
using namespace std;
typedef long long ll;
const int maxn=2e6+10;
int n,lenP,tot;
struct node{
    ll LD,LR,curLD,curLR,sz;
    int kind,fa;
}A[maxn];
map<string,int>mp[maxn];
string pathA[25];
vector<pair<int,string> >vecTmp;
void splitPath(string s){
     int i,lenS;
     string tmpS="";
     lenP=0;lenS=s.size();i=0;
     while(i<lenS){
        while(i<lenS&&(s[i]=='/'))i++;
        if(i>=lenS)break;
        tmpS="";
        while(i<lenS&&(s[i]!='/'))tmpS+=s[i],i++;
        if(tmpS=="")break;
        pathA[++lenP]=tmpS;
     }
}
void deleteNode(){
    int i,lenV,fa;
    string sec;
    lenV=vecTmp.size();
    for (i=0;i<lenV;i++){
        fa=vecTmp[i].first;sec=vecTmp[i].second;
        mp[fa].erase(mp[fa].find(sec));
    }
}
bool createFile(string path,ll sz){
     int i,j,fa,son,tmpTot,flag;
     ll delta;
     vecTmp.clear();
     splitPath(path);
     fa=0;tmpTot=tot;
     for (i=1;i<=lenP;i++){
         son=mp[fa][pathA[i]];
         if(i<lenP){
            if(son&&(A[son].kind==1)){
               deleteNode();return false;
            }
            if(!son){
                ++tmpTot;
                A[tmpTot]={0,0,0,0,0,2,fa};
                mp[fa][pathA[i]]=tmpTot;vecTmp.push_back(make_pair(fa,pathA[i]));
                fa=tmpTot;
            }
            else fa=son;
            continue;
         }
         if(son&&(A[son].kind==2)){
            deleteNode();return false;
         }
        if(!son){
          ++tmpTot;
          A[tmpTot]={0,0,0,0,0,1,fa};
          mp[fa][pathA[i]]=tmpTot;vecTmp.push_back(make_pair(fa,pathA[i]));
          delta=sz;son=tmpTot;
        }
        else delta=sz-A[son].sz;
        if(A[fa].LD&&(A[fa].LD<A[fa].curLD+delta)){
          deleteNode();return false;
        }
        for (j=fa;j!=-1;j=A[j].fa){
            if(A[j].LR&&(A[j].LR<A[j].curLR+delta)){
                deleteNode();return false;
            }
        }
        A[fa].curLD=A[fa].curLD+delta;
        for (j=fa;j!=-1;j=A[j].fa){
            A[j].curLR=A[j].curLR+delta;
        }
        A[son].sz=sz;
        tot=tmpTot;
     }
     return true;
}
void removeFile(string path){
     int i,j,son,fa;
     ll delta;
     splitPath(path);
     fa=0;
     for (i=1;i<=lenP;i++){
         son=mp[fa][pathA[i]];
         if(!son)return;
         if(i<lenP){
            fa=son;continue;
         }
         if(A[son].kind==1)delta=-A[son].sz;
         else delta=-A[son].curLR;
         if(A[son].kind==1)A[fa].curLD+=delta;
         for (j=fa;j!=-1;j=A[j].fa)A[j].curLR+=delta;
         mp[fa].erase(mp[fa].find(pathA[i]));
     }
}
bool allocate(string path,ll LD,ll LR){
     int i,son,fa;
     splitPath(path);
     if(!lenP){
        if(LD&&(LD<A[0].curLD))return false;
        if(LR&&(LR<A[0].curLR))return false;
        A[0].LD=LD;A[0].LR=LR;
        return true;
     }
     fa=0;
     for (i=1;i<=lenP;i++){
         son=mp[fa][pathA[i]];
         if(!son)return false;
         if(A[son].kind==1)return false;
         if(i<lenP){
            fa=son;continue;
         }
         if(LD&&(LD<A[son].curLD))return false;
         if(LR&&(LR<A[son].curLR))return false;
         A[son].LD=LD,A[son].LR=LR;
     }
     return true;
}
void init(){
     int i;
     tot=0;
     A[0]={0,0,0,0,0,2,-1};
     for (i=0;i<maxn;i++)mp[i].clear();
}
int main(){
    string op,path;
    ll sz,LD,LR;
    bool flag;
    while(cin>>n){
        init();
        while(n--){
           flag=true;
           cin>>op;
           if(op[0]=='C'){
                cin>>path>>sz;
                flag=createFile(path,sz);
            }
            else if(op[0]=='R'){
                cin>>path;
                removeFile(path);
            }
            else if(op[0]=='Q'){
                cin>>path>>LD>>LR;
                flag=allocate(path,LD,LR);
            }
            printf("%c\n",flag?'Y':'N');
        }
    }
    return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值