专栏文章
题解:CF2039D Shohag Loves GCD
CF2039D题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mio2j1ne
- 此快照首次捕获于
- 2025/12/02 12:18 3 个月前
- 此快照最后确认于
- 2025/12/02 12:18 3 个月前
数论 + 贪心构造
设最终的答案数组为 。
手玩一下数据:
当 时,显然对于任意的 都满足 ,那么要保证 ,即保证 。根据贪心策略不难想到让 取序列 中的最大值。
当 时,显然对于所有的 满足 ,那么要保证 ,即保证 。根据贪心策略将 设置为序列 中次大值。
当 时,同样地,显然对于所有的 满足 ,那么要保证 ,即保证 。同时,由于 是质数,对于任意的 都满足 ,那么要保证 ,显然这个式子一定成立,因为 且前面条件中保证了只有 能取序列 中的最大值。也就是说,只要 是质数,那么 取序列 中的次大值即为最优解。因此根据贪心策略 设置为序列 中次大值。
当 时,显然对于所有的 满足 ,那么要保证 ,即保证 。由于 是合数,因而 的取值不能和 的取值相同,其中 。因而 的最优取值就是序列 中的次次大值。
归纳一下,只要 为质数,那么 取序列 中的次大值;若 为合数,则 的取值要比 的所有约数 中对应的 的最小值 还要小,再根据贪心策略,让 尽可能大,即让 取序列 中小于 的最大值。
具体实现:我们可以将 数组降序排序得到 数组,用 记录 是取自序列 中的哪个下标的值。显然 ,而对于后续更新过程考虑 DP 转移即可。
ans 数组的 DP 转移方程:,其中 为 的倍数。
那么无解就很好判定了,显然当 时无解。
若采用枚举倍数的做法,调和级数时间复杂度 。当然也可以线性筛做到 。
PS:分析到这你就会发现实际上本题的 ans 数组和给定的 个数毫无关系,ans 数组你完全可以直接预处理。
CPPconst int N=1e5+5;
int n,m;
int a[N];
int ans[N];
void solve(){
cin>>n>>m;
rep(i,1,m) cin>>a[i];
sort(a+1,a+1+m,greater<int>());
ans[1]=1;
int mx=0;
rep(i,1,n){
for(int j=2*i;j<=n;j+=i){
ans[j]=max(ans[j],ans[i]+1);
mx=max(mx,ans[j]);
}
}
if(mx>m) cout<<-1;
else rep(i,1,n) cout<<a[ans[i]]<<" ";
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...