社区讨论

P14637[NOIP2025] 树的价值参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mloknx9i
此快照首次捕获于
2026/02/16 10:45
3 天前
此快照最后确认于
2026/02/16 10:53
3 天前
查看原帖
尽力了,卡不动了。代码都快卡成压缩面包了,还是超时。
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=8005,M=805,R=12;
struct sgt{
	int s[N];
	int lowbit(int x){
		return x&(-x);
	}
	void add(int x,int k){
		while(x<N){
			s[x]+=k;
			x+=lowbit(x);
		}
	}
	void upd(int x,int y,int k){
		add(x,k);
		add(y+1,-k);
	}
	int sum(int x){
		int res=0;
		while(x){
			res+=s[x];
			x-=lowbit(x);
		}
		return res;
	}
}ft[M],ht[M];
int n,m;
vector<int> e[N];
int sz[N],fr[N],dfn[N],dc;
int f[N][M],g[N][M];
int ne[N*M],to[N*M],he[N][M],cnt;
void add(int i,int j,int k){
	ne[++cnt]=he[i][j];
	to[cnt]=k;
	he[i][j]=cnt;
}
void cl(){
	n=m=dc=0;
	for(int i=0;i<N;i++){
		e[i].clear();
	}
	for(int j=0;j<M;j++){
		ft[j]=ht[j]=sgt();
	}
	memset(sz,0,sizeof(sz));
	memset(fr,0,sizeof(fr));
	memset(dfn,0,sizeof(dfn));
	memset(f,0,sizeof(f));
	memset(g,0,sizeof(g));
	memset(ne,0,sizeof(ne));
	memset(to,0,sizeof(to));
	memset(he,0,sizeof(he));
}
void dfs0(int u,int fa){
	fr[u]=fa;
	sz[u]=1;
	dfn[u]=++dc;
	for(int v:e[u]){
		dfs0(v,u);
		sz[u]+=sz[v];
	}
}
void dec(int i,int j,int val){
	if(f[i][j]>=val) return;
	int w=fr[i];
	if(w) ht[j].upd(dfn[w],dfn[w]+sz[w]-1,val-f[i][j]);
	ft[j].upd(dfn[i],dfn[i]+sz[i]-1,val-f[i][j]);
	f[i][j]=val;
}
void upd(int &x,int y){
	x=max(x,y);
}
void dfs2(int i){
	for(int v:e[i]){
		dfs2(v);
	}
	for(int j=1;j<=m;j++){
		upd(g[i][j],j*sz[i]);
		int sum=0;
		for(int w:e[i]){
			sum+=f[w][j];
		}
		for(int v:e[i]){
			upd(g[i][j],j+g[v][j+1]+sum-f[v][j]);
		}
		dec(i,j,j*sz[i]);
		if(j==1){
			dec(i,j,g[i][j]);
		}
		else{
			for(int l=he[i][j-1];l;l=ne[l]){
				int v=to[l];
				dec(i,j,j*(j-1)+g[v][j]+(ht[j].sum(dfn[fr[v]])-ht[j].sum(dfn[fr[i]]))-(ft[j].sum(dfn[v])-ft[j].sum(dfn[i])));
			}
		}
	}
}
void sol(){
	cin>>n>>m;
	m++;
	for(int i=2;i<=n;i++){
		int x;
		cin>>x;
		e[x].push_back(i);
	}
	dfs0(1,0);
	for(int i=1;i<=n;i++){
		int w=i,cnt=0;
		while(w){
			cnt++;
			w=fr[w];
			add(w,cnt,i);
		}
	}
	dfs2(1);
	int ans=max(f[1][1],g[1][1]);
	cout<<ans<<"\n";
	cl();
}
signed main(){
	freopen("tree.in","r",stdin);
	freopen("tree.out","w",stdout);
	ios::sync_with_stdio(0),cin.tie(0);
	int ct;
	cin>>ct;
	while(ct--){
		sol();
	}
}

回复

2 条回复,欢迎继续交流。

正在加载回复...