• One Theorem, One Year LightOJ


    题目链接

    题意:给你n和m,令x为前m个素数,一共使用n个的乘积,例如n=3,m=2,则x=2*2*3或x=2*3*3,求所有Φ(x)的和。

    思路:用到了欧拉函数的性质,首先对于x为素数,Φ(x)=x-1,然后若n*m=x,则Φ(n)*Φ(n)=Φ(x)。所以我们可以求出前500个素数,然后对其进行dp。

    dp[i][j]表示总共i个素数,前j个素数。因此对于dp[i][j]有两种情况,第一种为没用用到新素数,则为dp[i][j]+=dp[i-1][j]*prime[j],若用到了新素数,则为dp[i][j]+=dp[i-1][j-1]*(prime[j]-1)。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    typedef unsigned int uint;
    const int N = 1000010;
    const int maxn=1e8+5;
    ll mod=1e9+7;
    ll prime[N];
    int vis[N];
    int k=0;
    ll dp[1010][1010];
    ll qpow(ll base, int n)
    {
        ll a=base;
        ll res=1;
        while (n){
            if (n&1) res=(res*a)%mod;
            a=(a*a)%mod;
            n>>=1;
        }
        return res;
    }
    void init()
    {
        for(int i=2;i<=1000000;i++)
        {
            if(vis[i]==0)
            {
                prime[++k]=i;
                for(int j=i+i;j<=1000000;j+=i)
                {
                    vis[j]=1;
                }
            }
        }
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for(int i=1;i<=500;i++)
        {
            for(int j=1;j<=i;j++)
            {
                dp[i][j]=(dp[i][j]+dp[i-1][j]*prime[j]%mod)%mod;
                dp[i][j]=(dp[i][j]+dp[i-1][j-1]*(prime[j]-1)%mod)%mod;
            }
        }
    }
    void solve(ll n,ll m)
    {
        
    }
    int main() {
        int t;
        int u=0;
        init();
        scanf("%d",&t);
        while(t--){
            ll n,m;
            scanf("%lld%lld",&n,&m);
            printf("Case %d: ",++u);
            printf("%d
    ",dp[n][m]);
        }
    }
  • 相关阅读:
    sql行列转换问题 .
    JS常用正则表达式
    sql语句导入导出大全 .
    (国际)(2)“金环日食”
    java小问题总结1
    告诉你的安全方法:window xp双重加密
    专业解不是win32应用程序
    CSDN最HOT信息收藏
    DotNet 网上资源1(转贴)
    歪批IT之加班 IT就是我累了?
  • 原文地址:https://www.cnblogs.com/2462478392Lee/p/13714879.html
Copyright © 2020-2023  润新知