题解:P14637 [NOIP2025] 树的价值 / tree(官方数据)
nullptr_qwq_ · · 题解
考虑延迟钦定 dp:子树合并记录当前
上述做法二三维基于子树大小,但是题中限制是深度。考虑将继承
从状态的角度优化,
在树上从
#include<bits/stdc++.h>
#define ull unsigned long long
#define ll long long
#define uint unsigned
#define pb push_back
#define mkp make_pair
#define fi first
#define se second
#define inf 1000000000
#define infll 1000000000000000000ll
#define pii pair<int,int>
#define rep(i,a,b,c) for(int i=(a);i<=(b);i+=(c))
#define per(i,a,b,c) for(int i=(a);i>=(b);i-=(c))
#define F(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define dF(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define eb emplace_back
#define SZ(x) ((int)x.size())
#define all(x) x.begin(),x.end()
using namespace std;
bool ST;
void fre(){
// freopen("tree.in","r",stdin),freopen("tree.out","w",stdout);
}
inline int lowbit(int x){ return x&(-x); }
template<typename T>inline void chkmax(T &x,const T &y){ x=std::max(x,y); }
template<typename T>inline void chkmin(T &x,const T &y){ x=std::min(x,y); }
const int mod=998244353,maxn=8005,MR=805;
vector<int>g[maxn];
int n,m,fa[maxn];
struct BIT{
int t[maxn];
void init(){ memset(t,0,sizeof t); }
void add(int l,int r,int val){
if(l>r)return;
for(;l<=n;l+=lowbit(l))t[l]+=val;
for(++r;r<=n;r+=lowbit(r))t[r]-=val;
}
int qry(int x){
int res=0;
for(;x;x&=(x-1))res+=t[x];
return res;
}
}tr[MR];
int dfn[maxn],rev[maxn],tim,siz[maxn],ed[maxn],dep[maxn];
void dfs0(int u){
rev[dfn[u]=++tim]=u,siz[u]=1,dep[u]=dep[fa[u]]+1;
for(int&v:g[u])dfs0(v),siz[u]+=siz[v];
ed[u]=tim;
}
int f[maxn][MR],h[maxn][MR],sum[MR];
void solve(){
cin>>n>>m,++m,tim=0;
F(i,0,m)tr[i].init();
F(u,1,n)F(i,0,m)f[u][i]=h[u][i]=0;
F(i,1,n)g[i].clear();
F(i,2,n)cin>>fa[i],g[fa[i]].push_back(i);
dfs0(1);
dF(u,n,1){
F(i,0,m)sum[i]=0;
F(i,1,dep[u])f[u][i]=i*siz[u];
for(int&v:g[u])F(i,0,dep[u])sum[i]+=f[v][i];
F(i,1,dep[u])for(int&v:g[u])tr[i].add(dfn[v],ed[v],i+sum[i]-f[v][i]);
for(int&v:g[u])F(i,0,dep[u])chkmax(h[u][i],h[v][i+1]+sum[i]-f[v][i]);
F(i,1,dep[u])h[u][i]+=i;
F(i,dfn[u],ed[u]){
const int x=rev[i],d=dep[x]-dep[u]+1;
if(d<=dep[u])chkmax(f[u][d],h[x][d]+tr[d].qry(dfn[x]));
}
chkmax(f[u][0],h[u][1]);
}
cout<<f[1][0]<<'\n';
}
bool ED;
signed main(){
fre(),ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int wzq=1;cin>>wzq;
F(____,1,wzq)solve();
cerr<<"time used: "<<(double)clock()/CLOCKS_PER_SEC<<endl;
cerr<<"memory used: "<<abs(&ST-&ED)/1024.0/1024.0<<" MB"<<endl;
}
// g++ P14637.cpp -o a -std=c++14 -O2