【CF1333F】Kate and imperfection(埃氏筛+思维)

传送门

  • 题目:
    在这里插入图片描述
  • 思路:
    l e n len len =2~n内的质数个数+1,最多可以从 n n n中选取 l e n len len个数使得这些数组成的集合的 imperfection值为1。如果集合的大小 k ≤ l e n k\le len klen,那么总能选取 k k k个数使得他们之间两两互质,集合的imperfection值为1。
    考虑剩下的合数,依次从中选取 1 , 2 , 3... n − l e n 1,2,3...n-len 1,2,3...nlen个数加入到之前的 l e n len len个数组成的集合,且要求集合大小相同的情况下,集合的imperfection值最小。可以发现随着新加入的数的个数不断增多,集合的imperfection值是非递减的。
    对于一个合数 x x x,若其存在最小的因子 i i i,使得 i ∗ j = x i*j=x ij=x,那么加入该合数对集合imperfection值的最大贡献为 j j j。(如果集合中出现 j j j,那么该集合的imperfection值为 g c d ( j , x ) = j gcd(j,x)=j gcd(j,x)=j)。
    综上,2~n内的质数对答案的贡献为1,求出合数对答案的最大贡献,结合“集合的imperfection值是非递减的”这一性质,将得到的 n − 1 n-1 n1个值升序排序即可得到答案。
    可以在埃氏筛的过程中统计质数和合数对答案的贡献。
  • ac代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
const int maxn = 5e5+10;
int n;
vector<int> ans;
bool vis[maxn];
int main()
{
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
    scanf("%d", &n);
    for(int i = 2; i <= n; i++)
    {
        if(vis[i]) continue;
        ans.push_back(1);
        for(int j = i; j <= n/i; j++)
        {
            if(vis[i*j]) continue;
            ans.push_back(j);
            vis[i*j] = true;
        }
    }
    sort(ans.begin(), ans.end());
    for(int i = 0; i < ans.size(); i++) printf("%d%c", ans[i], i==ans.size()-1?'\n':' ');
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值