CSP 202012-3 带配额的文件系统 100分题解

csp该题链接

202012-3 带配额的文件系统

debug的最恶心的一道大模拟,又臭又长,直接上代码(703ms,17.22MB)

#pragma GCC optimize(2, 3, "Ofast", "inline")
#include <unordered_map>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
using ll = long long;
struct Idx
{
    ll sd = 0, sr = 0;
    ll ld = 0, lr = 0;
    unordered_map<string, Idx *> kidx;
    unordered_map<string, ll> kfil;
    ~Idx()
    {
        for (auto x : kidx)
            delete x.second;
    }
};
auto root = new Idx();
vector<string> split(string path)
{
    vector<string> ans;
    if (path == "")
        ans.push_back("");
    for (size_t i = 0, j = 0; i < path.size(); i = j + 1)
    {
        j = path.find('/', i);
        if (j == string::npos)
            j = path.size();
        ans.push_back(path.substr(i, j - i));
    }
    return ans;
}
Idx *getiptr(string path)
{
    auto sp = split(path);
    auto ptr = root;
    for (auto x : sp)
    {
        if (ptr->kidx.count(x))
            ptr = ptr->kidx[x];
        else
            return nullptr;
    }
    return ptr;
}
bool check(string path, ll ds)
{
    auto sp = split(path);
    auto ptr = root;
    for (auto x : sp)
    {
        ptr = ptr->kidx[x];
        if (ptr->sr + ds > ptr->lr && ptr->lr != 0)
            return 0;
    }
    return 1;
}
void mdf(string path, ll ds)
{
    auto sp = split(path);
    auto ptr = root;
    for (auto x : sp)
    {
        ptr = ptr->kidx[x];
        ptr->sr += ds;
    }
    return;
}
bool crei(string path)
{
    auto sp = split(path);
    auto x = sp.begin();
    auto ptr = root;
    for (; x != sp.end() - 1 && ptr->kidx.count(*x); x++)
        ptr = ptr->kidx[*x];
    if (ptr->kfil.count(*x))
        return 0;
    for (; x != sp.end(); x++)
    {
        ptr->kidx[*x] = new Idx();
        ptr = ptr->kidx[*x];
    }
    return 1;
}
bool cref(string path, ll size)
{
    string ppath = path.substr(0, path.find_last_of('/'));
    auto sp = split(path);
    if (getiptr(ppath) == nullptr)
    {
        auto tptr = root;
        for (auto x : sp)
        {
            if (tptr->kidx.count(x))
            {
                tptr = tptr->kidx[x];
                if (tptr->sr + size > tptr->lr && tptr->lr != 0)
                    return 0;
            }
            else
                break;
        }
        if (!crei(ppath))
            return 0;
    }
    auto pptr = getiptr(ppath);
    if (pptr->kidx.count(sp.back()))
        return 0;
    ll ds = size - (pptr->kfil.count(sp.back())?pptr->kfil[sp.back()]:0);
    if ((pptr->ld != 0 && pptr->sd + ds > pptr->ld) || !check(ppath, ds))
        return 0;
    mdf(ppath, ds);
    pptr->sd += ds;
    pptr->kfil[sp.back()] = size;
    return 1;
}
bool qur(string path, ll ld, ll lr)
{
    auto ptr = getiptr(path);
    if (ptr != nullptr)
        if ((ptr->sd <= ld || ld == 0) && (ptr->sr <= lr || lr == 0))
        {
            ptr->ld = ld;
            ptr->lr = lr;
            return 1;
        }
    return 0;
}
void rem(string path)
{
    string ppath = path.substr(0, path.find_last_of('/'));
    auto pptr = getiptr(ppath);
    auto sp = split(path);
    if (pptr == nullptr)
        return;
    else
    {
        ll ds;
        if (pptr->kfil.count(sp.back()))
        {
            ll s = pptr->kfil[sp.back()];
            pptr->sd -= s;
            ds = s;
            pptr->kfil.erase(sp.back());
        }
        else if (pptr->kidx.count(sp.back()))
        {

            auto ptr = pptr->kidx[sp.back()];
            ds = ptr->sr;
            delete ptr;
            pptr->kidx.erase(sp.back());
        }
        else
            return;
        mdf(ppath, -ds);
    }
    return;
}
int main()
{
    root->kidx[""] = new Idx();
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    char v;
    string temp;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> v >> temp;
        if (v == 'C')
        {
            ll s;
            cin >> s;
            cout << (cref(temp, s) ? 'Y' : 'N');
        }
        else if (v == 'Q')
        {
            ll d, r;
            cin >> d >> r;
            cout << (qur(temp, d, r) ? 'Y' : 'N');
        }
        else if (v == 'R')
        {
            rem(temp);
            cout << 'Y';
        }
        cout << endl;
    }
    delete root;
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值