专栏文章

[CF2112E] Tree Colorings 题解

CF2112E题解参与者 1已保存评论 0

文章操作

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

当前评论
0 条
当前快照
1 份
快照标识符
@min5dpuj
此快照首次捕获于
2025/12/01 20:50
3 个月前
此快照最后确认于
2025/12/01 20:50
3 个月前
查看原文
注意到赛事公告提醒了第三组数据的问题,即任意一对绿色点之间没有黄色和蓝色点。于是绿色点是一个连通块。
然后就有一个很明显的 dp,设 fuf_u 表示以 uu 为根的子树方案数,这里令 uu 为绿色。于是转移时每棵儿子的子树独立,并且额外有全涂蓝色或黄色两种情况,于是转移 fu=vson(u)(fv+2)f_u=\prod_{v\in\text{son}(u)}(f_v+2)
然后对于原问题,尝试直接拼起来 dp,然后发现根节点比较恼人,因为不知道到底要分拆出来哪些东西。于是换一个思路,在一棵树的基础上再加上一个儿子,则有 fu(fv+2)fuf_u(f_v+2)\to f'_{u},这样就有一个明显的递推。设 gig_i 表示原问题 m=im=i 时的答案,则 gdgxd2gxg_{d}g_{\frac xd-2}\to g_x,其中 dxd\mid x。具体实现时钦定 dxdd\ge \frac xd 然后分别执行 gdgxd2gx,gd2gxdgxg_dg_{\frac xd-2}\to g_x,g_{d-2}g_{\frac xd}\to g_x 即可。
时间复杂度调和级数级。
codeCPP
#include<bits/stdc++.h>
#define pb emplace_back
#define mp make_pair
#define pob pop_back
using namespace std;
typedef long long ll;
const ll maxn=500007,ee=1e18;
ll n,f[maxn],cnt;
int main(void){
	freopen("data.in","r",stdin);
	freopen("data.out","w",stdout);
	ios::sync_with_stdio(0),cin.tie(0);
	memset(f,0x3f,sizeof(f));
	f[1]=1;
	for(ll d=1;d<maxn;d++){
		for(ll x=d,i=1;x<maxn&&i<=d;x+=d,i++){
			if(i>=3) f[x]=min(f[x],f[d]+f[i-2]);
			if(d>=3) f[x]=min(f[x],f[d-2]+f[i]);
		}
	}
	ll T=1; cin>>T;
	for(;T--;){
		cin>>n;
		if(f[n]>=ee) cout<<"-1\n";
		else cout<<f[n]<<"\n";
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...