csp该题链接
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;
}