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

原题链接:带配额的文件系统
在这里插入图片描述这道题真的很!!复!!杂!!

真的写不出来。。。。。既然写不出来!那就参考别人的吧: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;
}
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值