没看题解, 独立拗了两个小时才写完…
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
class File {
public:
bool isFolder;
string name;
LL size; // size of the file, enabled only if it is file
LL cd; // current direct size, enabled only if it is folder
LL cr; // current recursive size
LL LD;
LL LR;
map<string, File*> subFiles;
void deleteSubFolder() {
for (auto p: subFiles) {
p.second->deleteSubFolder();
}
for (auto p: subFiles) {
delete p.second;
}
}
File(bool _isFolder, string _name, LL _size)
{
this->isFolder = _isFolder;
this->name = _name;
this->size = _size;
this->cd = this->cr = 0;
this->LD = this->LR = 0;
}
};
class FS {
File *root;
vector<string> splitPath(string path) {
int l = 0, r = 0;
vector<string> ret;
int n = path.length();
while(r < n) {
if (path[r] != '/') {
++r;
}
else {
// [l, r)
if (l != r) ret.push_back(path.substr(l, r - l));
r++;
l = r;
}
}
if (l != r) {
ret.push_back(path.substr(l, r - l));
}
return ret;
}
public:
FS() {
root = new File(true, "root", 0);
}
bool newFile(string path, LL size) {
vector<string> p = splitPath(path);
LL prevSize = 0;
// check if the name is used
File *cur = root;
for (int i = 0; i < p.size(); i++) {
if (cur->subFiles.find(p[i]) != cur->subFiles.end()) {
// exists
if (i == p.size() - 1) {
if (cur->subFiles[p[i]]->isFolder) {
return false;
}
else {
// the file already exists, so is update, not new
prevSize = cur->subFiles[p[i]]->size;
}
}
else {
if (!cur->subFiles[p[i]]->isFolder) {
return false;
}
else {
cur = cur->subFiles[p[i]];
}
}
}
else {
// need to create
break;
}
}
// check quota
cur = root;
for (int i = 0; i < p.size(); i++) {
if (i == p.size() - 1 && cur->LD != 0 && cur->cd + size - prevSize > cur->LD) return false;
if (cur->LR != 0 && cur->cr + size - prevSize > cur->LR) return false;
if (cur->subFiles.find(p[i]) != cur->subFiles.end()) cur = cur->subFiles[p[i]];
else break;
}
// create subFolders
cur = root;
for (int i = 0; i < p.size() - 1; i++) {
if (cur->subFiles.find(p[i]) == cur->subFiles.end()) {
// need to create subfolder
cur->subFiles[p[i]] = new File(true, p[i], 0);
}
cur = cur->subFiles[p[i]];
}
// create file
cur = root;
for (int i = 0; i < p.size() - 1; i++) {
cur->cr += (size - prevSize);
cur = cur->subFiles[p[i]];
}
if (cur->subFiles.find(p.back()) != cur->subFiles.end()) {
// so the file already exists
cur->cd += (size - prevSize);
cur->cr += (size - prevSize);
cur->subFiles[p.back()]->size = size;
}
else {
cur->cd += (size - prevSize);
cur->cr += (size - prevSize);
cur->subFiles[p.back()] = new File(false, p.back(), size);
}
return true;
}
bool deleteFile(string path) {
vector<string> p = splitPath(path);
LL size = 0;
bool isFolder = false;
// check if exists
File *cur = root;
for (int i = 0; i < p.size(); i++) {
if (cur->subFiles.find(p[i]) == cur->subFiles.end()) {
return true;
}else {}
if (i == p.size() - 1) {
File * tmp = cur->subFiles[p[i]];
cur->subFiles.erase(p[i]);
cur = tmp;
}
else {
cur = cur->subFiles[p[i]];
}
}
if (cur->isFolder) {
size = cur->cr;
isFolder = true;
cur->deleteSubFolder();
delete cur;
}
else {
size = cur->size;
delete cur;
}
// update quota
cur = root;
for (int i = 0; i < p.size() - 1; i++) {
cur->cr -= size;
cur = cur->subFiles[p[i]];
}
cur->cr -= size;
if (!isFolder) cur->cd -= size;
return true;
}
bool changeQuota(string path, LL LD, LL LR) {
vector<string> p = splitPath(path);
File *cur = root;
for (int i = 0; i < p.size(); i++) {
if (cur->subFiles.find(p[i]) == cur->subFiles.end()) {
return false;
}
else {
cur = cur->subFiles[p[i]];
}
}
if (!cur->isFolder) return false;
if (LD != 0 && cur->cd > LD) {
return false;
}
if (LR != 0 && cur->cr > LR) {
return false;
}
cur->LD = LD;
cur->LR = LR;
return true;
}
};
int N;
int main() {
FS fs;
cin >> N;
while(N --) {
char C;
cin >> C;
if (C == 'C') {
string path;
LL size;
cin >> path >> size;
bool res = fs.newFile(path, size);
if (res) puts("Y");
else puts("N");
}
else if (C == 'R') {
string path;
cin >> path;
bool res = fs.deleteFile(path);
if (res) puts("Y");
else puts("N");
}
else {
// C == 'Q
string path;
LL LD, LR;
cin >> path >> LD >> LR;
bool res = fs.changeQuota(path, LD, LR);
if (res) puts("Y");
else puts("N");
}
}
return 0;
}