• Sum of a Function(区间筛)


    每个人都知道Arup喜欢素数! 这就是为什么他在UCF教授密码学课程。 最近,Arup对大于1的正整数n定义了以下函数:

    f(n)是的n最小质因子。

    例如,f(14)= 2,f(15)= 3,f(16)= 2和f(17)= 17。

    使用此函数,我们可以生成一系列项f(s),f(s + 1),f(s +2),…,f(e),其中s表示开始函数输入,e表示结束函数 输入。

    奥雅纳(Arup)认为这些序列很有趣,但是他真正好奇的是找到其中一个序列中k个最小元素的总和。 你能写一个程序来帮助他吗?

    给定s,e和k,找到序列f(s),f(s + 1),f(s +2),…,f(e)中的k个最小值的总和。

    第一行也是唯一的输入行将包含三个正整数,即s(2≤s≤1e18),e(s +100≤e≤s + 106)和k(1≤k≤0.9 *(e – s + 1) ),分别代表开始函数输入,结束函数输入和要累加的最小项数。

    单独在一行上打印指定序列的k个最小项的总和。

    样例1】
    100200 70
    【样例2】
    213419169
    样例输出复制
    【样例1】
    165
    【样例2】
    546
    提示
    即使输入规范不允许将“ 14 17 3”作为输入条件(即,该条件将不在判断数据中),但您还是可能希望将其用于测试目的,这是一个简单的情况-输出(7 )可以在纸上轻松验证。 (顺便说一句,预期的解决方案无论如何应能正确解决此问题。)

    题目意思:就是定义了一个f(n)就是n的最小质因子,给你一个s,e,k,就是找区间s到e中所有f(n)排序后最小的k个。但是s,e,很大

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 5000010;
    int f[N];
    int prime[N],cnt;
    bool vis[N];
    bool dabiao[N];
    void get_prime()
    {
        for(int i=2;i<N;i++)
        {
            if(!vis[i]) prime[cnt++] = i,f[i]=i;
            for(int j=0;prime[j]*i<N;j++)
            {
                if(!f[prime[j]*i]) f[prime[j]*i]=prime[j];
                vis[i*prime[j]]=true;
                if(i%prime[j]==0) break;
            }
        }
    }
    void qujianshai(ll l,ll r){
        memset(f,0,sizeof f);
        for(ll i=0;i < cnt&&prime[i]*prime[i]<=r;i++){
            for(ll j=max(2LL,(l+prime[i]-1)/prime[i])*prime[i];j<=r;j+=prime[i]){
                if(j>=l){
                    dabiao[j-l]=1;//1是合数 
                    if(f[j-l]==0) f[j-l] = prime[i];
                }
            }
        }
    }
    ll st[N],t;
    int main()
    {
        get_prime();
        ll s,e,k;
        f[1]=1;
        cin>>s>>e>>k;
        qujianshai(s,e);
        for(ll i=0;i<=e-s;i++){
            if(dabiao[i]==0){ 
                st[++t]=i+s;
            }
            else{
                st[++t]=f[i];
            }
        }
        sort(st+1,st+t+1);
        ll ans=0;
        for(int i=1;i<=k;i++){
            ans+=st[i];
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    健康检查详解:机制、配置、对比、实操
    制作自签名证书
    常用的UML建模
    UML建模更好的表达产品逻辑
    常用的UML建模
    UML建模图实战笔记
    领域驱动设计学习之路—DDD的原则与实践
    DDD领域驱动设计理论篇
    WAN、LAN、WLAN三种网口的区别
    新生代Eden与两个Survivor区的解释
  • 原文地址:https://www.cnblogs.com/lipu123/p/13796252.html
Copyright © 2020-2023  润新知