• 2017多校第9场 HDU 6169 Senior PanⅡ 数论,DP,爆搜


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6169

    题意:给了区间L,R,求[L,R]区间所有满足其最小质数因子为k的数的和。

    解法:

    我参考的这篇blog。http://blog.csdn.net/wubaizhe/article/details/77484454#cpp

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const LL mod = 1e9+7;
    const int Mx = 320000;
    const int A = Mx + 10;
    const int B = 1e4+10;
    const int C = 1e2+10;
    const LL inv = 500000004;
    LL dp[B][C];
    //dp[i][j]表示1~i 这 i个数被前j个素数筛过以后剩下的数的和。
    //dp[i][j]=dp[i][j−1]−pri[j]∗dp[i/pri[j]][j−1]
    int prime[A],tot;
    bool isprime[A];
    void predeal(){
        tot=0;
        memset(isprime, 1, sizeof(isprime));
        for(LL i=2; i<A; i++){
            if(isprime[i]){
                for(LL j=i+i; j<A; j+=i){
                    isprime[j]=0;
                }
            }
        }
        for(int i=2; i<A; i++){
            if(isprime[i]) prime[++tot] = i;
        }
        for(int i=1; i<B; i++)
        {
            dp[i][0] = 1LL*i*(i+1)/2%mod;
            for(int j=1; j<C; j++)
            {
                dp[i][j] = (dp[i][j-1] -  prime[j]*dp[i/prime[j]][j-1]%mod + mod)%mod;
            }
        }
    }
    LL dfs(LL n, LL m)
    {
        if(n<=1) return n;
        if(!m) return n%mod*(n%mod+1)%mod*inv%mod;
        if(n<B&&m<C) return dp[n][m];
        if(prime[m]>n) return 1;
        return (dfs(n,m-1)-prime[m]*dfs(n/prime[m],m-1)%mod+mod)%mod;
    }
    bool check(LL x){
        for(LL i=2; i*i<=x; i++){
            if(x%i==0){
                return false;
            }
        }
        return true;
    }
    int main()
    {
        predeal();
        int T,ks=0;
        scanf("%d", &T);
        while(T--)
        {
            LL L,R,k;
            scanf("%lld%lld%lld", &L,&R,&k);
            printf("Case #%d: ", ++ks);
            if(!check(k)){
                puts("0");
            }
            else if(k>Mx){
                if(L<=k&&k<=R) printf("%lld
    ",k%mod);
                else puts("0");
            }
            else{
                int now=0;
                while(prime[now+1]<k) now++;
                LL ans = (dfs(R/k,now)*k%mod-dfs((L-1)/k,now)*k%mod + mod)%mod;
                if(ans < 0) ans+=mod;
                printf("%lld
    ", ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    如何编写高质量的VB代码(转自雪中漫步的专栏)
    写好软件的75条(转)
    .NET在SQL Server中的图片存取技术(转)
    股票基础知识
    ActiveX组件及其注册
    面试之中企动力
    海量数据库的查询优化及分页算法方案(转)
    什么是Ajax(转)
    VB.Net2005使用windows media player 初探
    done sonatus 无人车startup阴区区烙印
  • 原文地址:https://www.cnblogs.com/spfa/p/7420374.html
Copyright © 2020-2023  润新知