专栏文章
[CF2112E] Tree Colorings 题解
CF2112E题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min5dpuj
- 此快照首次捕获于
- 2025/12/01 20:50 3 个月前
- 此快照最后确认于
- 2025/12/01 20:50 3 个月前
注意到赛事公告提醒了第三组数据的问题,即任意一对绿色点之间没有黄色和蓝色点。于是绿色点是一个连通块。
然后就有一个很明显的 dp,设 表示以 为根的子树方案数,这里令 为绿色。于是转移时每棵儿子的子树独立,并且额外有全涂蓝色或黄色两种情况,于是转移 。
然后对于原问题,尝试直接拼起来 dp,然后发现根节点比较恼人,因为不知道到底要分拆出来哪些东西。于是换一个思路,在一棵树的基础上再加上一个儿子,则有 ,这样就有一个明显的递推。设 表示原问题 时的答案,则 ,其中 。具体实现时钦定 然后分别执行 即可。
时间复杂度调和级数级。
code
CPP#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 条评论,欢迎与作者交流。
正在加载评论...