CF1499F - Diameter Cut

题意:对于一棵树,有多少种删去边的方式,使得删边之后得到的森林中,每棵树的直径都不超过 k

见数据范围和直径知 dp,设 dpi,j 表示当前考虑子树 i,所有直径不大于 k,且从 i 往下最深深度为 j 的方案数。

同时注意每棵树转移到祖先的时候,j 都要自增 1,而 dpi,0 就变成了所有 dpi 的和,因为就是对所有满足条件的 i 的方案,都把祖先这条边切掉。

下面我们默认转移时使用的 dp 数组是经过修改的,得到的 dp 数组是未经过修改的。

然后考虑转移,首先,对于 jk/2,我们可以直接转移,因为只要在每个儿子节点都满足 jk/2 即可。也就是 bSip=0jdpb,p。然后这个我们可以预处理每个 dp 数组的前缀和,求每个 j 的时候都扫一遍乘起来。因为每个节点会被父亲的每个 j 扫一次,所以这一步的复杂度是有保证的。

其次我们这里是找到了所有深度不大于 j 的方案数,要精确得到 j 的方案数需要做一次差分。

然后,对于 j>k/2 我们注意到只能有一个节点满足深度为 j,那么我们就枚举这个节点 x,并且为了直径合法,其他的选择不能超过 kj,所以答案就是 xSyS,yxp=0kjdpy,p

显然后面的东西可以用前缀后缀预处理出来,也就是我们可以处理 prei,j 表示将前缀的所有 sumi,j 乘起来,sufi,j 表示将后缀的所有 sumi,j 乘起来,然后我们只需要枚举 x,然后把 prex1,kjsufx+1,kj 乘起来,再乘上 dpx,j 即可。复杂度依旧有保证。

到这里我们就做完了题目,时间复杂度 O(nk)。但是空间复杂度也是 O(nk),要开 dp,sum,pre,suf 四个数组,跑不过去。

首先,习惯乱开 long long 的要关掉,做乘法的时候先乘 1ll 再运算,强转一下死不了人的。这样空间就是 400MB

然后我们发现,pre,suf 两个数组都只有 jk/2 的部分有效,第二维只开 2500 就够了,300MB

最后,我们发现上述过程,dpj 只在第二个转移乘了一次,完全可以现场用 sum 差分得到。所以我们可以用 sum 代替 dp 数组的作用。同时,我们第一类转移本来就是算出的 sum,改成 dp 本来就是浪费时间,还能优化效率,200MB。到这里就可以过了。

我们再次发现,presuf 没必要对于所有的 j 都处理出来,只要每次转移 dpi,j 之前把 kj 的先处理一遍就行。而且 pre 也没必要处理,完全可以一边 dp 一边处理,这样就只有 100MB 了,稳过,开 long long 也行。


const int P=998244353;
int n,k,dp[5005][5005],a,b;
vt<int>vv[5005];
int lis[5005],sz;
int sum[5005];
int suf[5005];
inline void dfs(int x,int p){
	for(auto j:vv[x])if(j!=p)dfs(j,x);
	sz=0;
	for(auto j:vv[x])if(j!=p)lis[++sz]=j;
	rep(j,0,k/2){
		dp[x][j]=1;
		rep(i,1,sz)dp[x][j]=1ll*dp[x][j]*dp[lis[i]][j]%P;
	}
	rep(j,k/2+1,k){
		dp[x][j]=dp[x][j-1];
		suf[sz+1]=1;
		per(i,1,sz)suf[i]=1ll*suf[i+1]*dp[lis[i]][k-j]%P;
		ll pre=1;
		rep(i,1,sz){
			dp[x][j]=(dp[x][j]+(dp[lis[i]][j]-dp[lis[i]][j-1]+P)%P*1ll*pre%P*suf[i+1]%P)%P;
			pre=1ll*pre*dp[lis[i]][k-j]%P;
		}
	}int sum=dp[x][k];
	per(i,1,k+1)dp[x][i]=(dp[x][i-1]+sum)%P;
	dp[x][0]=sum;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>k;
	rp(i,n-1){
		cin>>a>>b;
		vv[a].pb(b);
		vv[b].pb(a);
	}
	dfs(1,0);
	cout<<(dp[1][k+1]-dp[1][0]+P)%P<<endl;
	return 0;
}
//Crayan_r
posted @   jucason_xu  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示