思路
离线建出版本树,需要支持在两端加入删除并维护背包,形如 deque。维护两个栈,一头一尾,分别维护背包, 合并两个背包。复杂度 。
code
int q,idx,tot,cntq;
int rt[maxn],ans[maxn];
vector<pii> que[maxn];
vector<pair<int,pii>> e[maxn];
vector<pii> st,ed;
int f[maxn][maxv],g[maxn][maxv];
void addback(int p,int t){
ed.pb({p,t});int tim=ed.size();
for(int i=0;i<=maxv-10;i++)g[tim][i]=g[tim-1][i];
for(int i=p;i<=maxv-10;i++)g[tim][i]=max(g[tim][i],g[tim-1][i-p]+t);
}
void addfront(int p,int t){
st.pb({p,t});int tim=st.size();
for(int i=0;i<=maxv-10;i++)f[tim][i]=f[tim-1][i];
for(int i=p;i<=maxv-10;i++)f[tim][i]=max(f[tim][i],f[tim-1][i-p]+t);
}
void rebuild(){
for(int tim=1;tim<=ed.size();tim++){
auto[p,t]=ed[tim-1];
for(int i=0;i<=maxv-10;i++)g[tim][i]=g[tim-1][i];
for(int i=p;i<=maxv-10;i++)g[tim][i]=max(g[tim][i],g[tim-1][i-p]+t);
}
for(int tim=1;tim<=st.size();tim++){
auto[p,t]=st[tim-1];
for(int i=0;i<=maxv-10;i++)f[tim][i]=f[tim-1][i];
for(int i=p;i<=maxv-10;i++)f[tim][i]=max(f[tim][i],f[tim-1][i-p]+t);
}
}
void rebuildfront(){
int pos=(ed.size()+1)/2;
for(int i=0;i<pos;i++)st.pb(ed[i]);
reverse(st.begin(),st.end());
reverse(ed.begin(),ed.end());
for(int i=1;i<=pos;i++)ed.pop_back();
reverse(ed.begin(),ed.end());
rebuild();
}
void rebuildback(){
int pos=(st.size()+1)/2;
for(int i=0;i<pos;i++)ed.pb(st[i]);
reverse(ed.begin(),ed.end());
reverse(st.begin(),st.end());
for(int i=1;i<=pos;i++)st.pop_back();
reverse(st.begin(),st.end());
rebuild();
}
pii popfront(){
if(!st.size())rebuildfront();
pii p=st.back();st.pop_back();
return p;
}
pii popback(){
if(!ed.size())rebuildback();
pii p=ed.back();ed.pop_back();
return p;
}
int query(int v){
int ans=0;
for(int i=0;i<=v;i++)ans=max(ans,f[st.size()][i]+g[ed.size()][v-i]);
return ans;
}
void dfs(int u){
for(auto[v,id]:que[u])ans[id]=query(v);
for(auto[v,p]:e[u]){
if(!p.fi){
pii w=popfront();
dfs(v);
addfront(w.fi,w.se);
}
else{
addback(p.fi,p.se);
dfs(v);
popback();
}
}
}
void work(){
q=read();rt[1]=idx=tot=1;
while(q--){
int opt=read();
if(opt==1){
int x=read();
rt[++idx]=rt[x];
}
if(opt==2){
int x=read(),p=read(),t=read();
e[rt[x]].pb({++tot,{p,t}}),rt[x]=tot;
}
if(opt==3){
int x=read();
e[rt[x]].pb({++tot,{0,0}}),rt[x]=tot;
}
if(opt==4){
int x=read(),p=read();
que[rt[x]].pb({p,++cntq});
}
}
dfs(1);
for(int i=1;i<=cntq;i++)printf("%lld\n",ans[i]);
}