再也不想做模拟题了
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+5;
typedef long long ll;
string s[N];
int cnt,idx; //idx为节点的唯一编号
struct node{
ll ld,lr,d,r,g; //kind 类型 1为普通文件,2为目录文件
int id;
};
typedef pair<ll,ll> pll;
unordered_map<string,node> f[N];//N为id号/string为子节点string名
void getp() {
string str; cin>>str;
int j=0,len=str.size();cnt=0;
for(int i=1;i<len;i++ ){
if(str[i]=='/') //没有哈希
s[++cnt]=str.substr(j+1,i-j-1),j=i;
} //最后一个
if(j!=len-1) s[++cnt]=str.substr(j+1,len-j-1);
return ;
}
ll find(int x,int k) { //判断路径是否满足
auto it=f[x].find(s[k]);
if(it==f[x].end()) return 0; //没找到
if(it!=f[x].end()) { //找到了
if(it->second.g) return k==cnt?it->second.g:-1;
else if(k==cnt) return -1;//目录文件,在创建文件位置
else return find(it->second.id,k+1); //全是目录文件
}
}
bool create(int x,int k,ll val ) {
auto it=f[x].find(s[k]);
if(k==cnt) { //递归结束条件
if(it!=f[x].end() ) it->second.g+=val;
else f[x][s[k]]={0,0,0,0,val,++idx};
return 1;
}
if(it==f[x].end()) //frist为插入元素的值
it=f[x].insert( {s[k],{0,0,0,0,0,++idx} } ).first;
if(k==cnt-1&&it->second.ld&&it->second.ld<val+it->second.d) return 0;
if(it->second.lr&&it->second.lr<val+it->second.r) return 0;
bool res=create(it->second.id,k+1,val);//dfs回溯
if(res&&(k==cnt-1) ) it->second.d+=val;
if(res) it->second.r+=val;
return res;
}
pll remove(int x,int k) { //x为父节点编号,k为路径中的位置
auto it=f[x].find(s[k]);//返回的是迭代器指针
if(it==f[x].end()) return {0,0} ; //返回值为到成功删除的文件大小
if(k==cnt) {
queue<ll> q; q.push(it->second.id); //文件对应的map清空
while(q.size() ){
for(auto y:f[q.front()]) q.push(y.second.id);
f[q.front()].clear(); q.pop();
}
f[x].erase(it);
return {it->second.g,it->second.r+it->second.g};//本文件/后代文件+本文件大小
}
pll cur=remove(it->second.id,k+1);//dfs回溯
if(cur.first) it->second.d-=cur.first,cur.first=0; //更新孩子节点
it->second.r-=cur.second;
return cur;
}
bool query(ll ld,ll lr) { //不用dfs回溯
for(ll k=0,x=0;k <=cnt;k++) {
auto it=f[x].find(s[k]);
if(it==f[x].end()||it->second.g)
return 0; //没有找到或者为普通文件
if(k==cnt) {
if((ld&&ld<it->second.d)||(lr&&lr<it->second.r))//不合法
return 0;
it->second.ld=ld; it->second.lr=lr; //更新配额值
}
x=it->second.id; //下一个节点的父节点
}
return 1;
}
int main(){
ios::sync_with_stdio(false); cin.tie(0);cout.tie(0);
int n; cin>>n;
f[0]["_root"]=node{0,0,0,0,0,++idx};
s[0]="_root"; //每个路径从根开始,必有数据
while(n--) {
char ch; cin>>ch; bool ans=0;
getp() ;
if(ch=='C') {
ll w; cin>>w;
ll res=find(0,0); //path 在s中,res为原值的大小
if(res!=-1) {
if(create(0,0,w-res)) ans=1; //成功
}
}
else if(ch=='R') {
remove(0,0); ans=1;
} else {
ll ld,lr; cin>>ld>>lr;
ans=query(ld,lr) ;
}
if(ans) cout<<"Y\n"; else cout<<"N\n";
}
return 0;
}
好厉害,我的代码比你的三倍还长Q
反了吧,可能先自己写最好