CCF 202012-3 带配额的文件系统 //大模拟 100%

题目

题意

模拟一个文件系统,要求此文件系统实现目录功能,创建文件功能,删除文件功能,以及对子树的文件大小之和配置限额。

思路

大模拟,注意到文件系统树的高度小于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;
}

  • 11
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值