第一次感受到CSP大模拟的险恶 。。。
太考验细心了
这个故事告诉了我大模拟一定得放到最后做,要不然改了一个多小时后两道题都没时间了
其实最后的30分是因为我的递归函数的返回值忘改成long long了
简单说一下思路:
很显然这是一个树型结构,每个节点保存这几个值:文件类型,目录配额,后代配额,孩子文件的总大小,后代文件的总大小,再开一个map记录儿子节点
创建文件是记录记录一下经过哪些节点,如果创建成功就就更新这些节点,否则就不更新,并且让新建的文件消除
删除文件时如果成功就记录sz为删除文件的后代文件的总大小,否则sz=0,回溯时每个文件的节点的后代文件的总大小都要减去sz,如果删除文件为普通文件,就让它的父亲的孩子文件的总大小减去sz
设定配额值就很简单,不能递归到目标文件则失败,如果能,那么递归到目标文件后判断能否修改即可
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define db double
#define rep(x,a,b) for(int x=(a);x<=(b);x++)
#define per(x,a,b) for(int x=(a);x>=(b);x--)
#define scf(a) scanf("%d",&a)
#define scfll(a) scanf("%lld",&a)
#define scfdb(a) scanf("%lf",&a)
#define ptf(a) printf("%d",a)
#define ptfll(a) printf("%lld",a)
#define ptfdb(x,a) printf("%x.lf",a)
#define ptfsp(a) printf("%d ",a)
#define ptfllsp(a) printf("%lld ",a)
#define ptfdbsp(x,a) printf("%x.lf ",a)
#define pli(a,b) make_pair(a,b)
#define pb push_back
#define el puts("")
#define pi 3.1415926
//ios::sync_with_stdio(false);
using namespace std;
const ll mod=1e9+7;
const int maxn=2e5+5;
struct node{
int FileType;
ll ld,lr,siz,subsiz;
map<string,int>mp;
}p[maxn];
string str;
int cnt=1;
vector<string>gs;
vector<int>gp;
ll siz,nld,nlr;
void getpath(string str){
int len=str.size();
str[len]='/';
int l=0,r=0;
gs.clear();
while(r+1<=len){
if(str[r+1]=='/'){
r++;
string ns=str.substr(l+1,r-l-1);
l=r;
gs.pb(ns);
}
else r++;
}
}
ll dsiz;
bool dfsc(int now,int dep){
gp.pb(now);
int nxt=p[now].mp[gs[dep]];
if(dep==gs.size()-1){
if(nxt){
if(p[nxt].FileType==1) return 0;
dsiz=siz-p[nxt].siz;
if(p[now].siz+dsiz>p[now].ld) return 0;
for(int i=0;i<gp.size();i++) if(p[gp[i]].subsiz+dsiz>p[gp[i]].lr) return 0;
p[now].siz+=dsiz;
for(int i=0;i<gp.size();i++) p[gp[i]].subsiz+=dsiz;
p[nxt].siz=p[nxt].subsiz=siz;
return 1;
}
else{
dsiz=siz;
if(p[now].siz+dsiz>p[now].ld) return 0;
for(int i=0;i<gp.size();i++) if(p[gp[i]].subsiz+dsiz>p[gp[i]].lr) return 0;
p[now].siz+=dsiz;
for(int i=0;i<gp.size();i++) p[gp[i]].subsiz+=dsiz;
p[now].mp[gs[dep]]=++cnt;
p[cnt].FileType=2;
p[cnt].siz=p[cnt].subsiz=siz;
return 1;
}
}
if(nxt){
if(p[nxt].FileType==2) return 0;
return dfsc(nxt,dep+1);
}
else{
nxt=p[now].mp[gs[dep]]=++cnt;
p[nxt].FileType=1;
p[nxt].ld=p[nxt].lr=2e18;
p[nxt].siz=p[nxt].subsiz=0;
p[nxt].mp.clear();
bool flag=dfsc(nxt,dep+1);
if(!flag) p[now].mp[gs[dep]]=0;
return flag;
}
}
ll dfsr(int now,int dep){
int nxt=p[now].mp[gs[dep]];
if(!nxt) return 0;
if(dep==gs.size()-1){
p[now].mp[gs[dep]]=0;
p[now].subsiz-=p[nxt].subsiz;
if(p[nxt].FileType==2) p[now].siz-=p[nxt].subsiz;
return p[nxt].subsiz;
}
if(p[nxt].FileType==2) return 0;
ll sz=dfsr(nxt,dep+1);
p[now].subsiz-=sz;
return sz;
}
bool dfsq(int now,int dep){
int nxt=p[now].mp[gs[dep]];
if(!nxt) return 0;
if(p[nxt].FileType==2) return 0;
if(dep==gs.size()-1){
if(nld<p[nxt].siz||nlr<p[nxt].subsiz) return 0;
p[nxt].ld=nld;
p[nxt].lr=nlr;
return 1;
}
return dfsq(nxt,dep+1);
}
int main(){
int T;scf(T);
int rt=1;
p[rt].FileType=1;
p[rt].ld=p[rt].lr=2e18;
p[rt].siz=p[rt].subsiz=0;
p[rt].mp.clear();
p[rt].mp[""]=rt;
while(T--){
char c;cin>>c;
cin>>str;
getpath(str);
if(c=='C'){
scfll(siz);
gp.clear();
puts(dfsc(rt,0)?"Y":"N");
}
if(c=='R'){
dfsr(rt,0);
puts("Y");
}
if(c=='Q'){
scfll(nld),scfll(nlr);
if(nld==0) nld=2e18;
if(nlr==0) nlr=2e18;
puts(dfsq(rt,0)?"Y":"N");
}
}
}