LightOj 1298

来源:互联网 发布:herry it 编辑:程序博客网 时间:2024/06/06 03:10

题目大意:

已知k,p,求φ(xi), xi=kai, ai为素数表前p位的数,其中kp;

思路:

φ(c)=φ(n)φ(m),  其中 c=mn,  gcd(m,n)=1;
φ(n)=n1;n为素数;
可以枚举1k个数,
如果为没有出现过的数,即该数与枚举到当前情况的积互素,乘以prime[i]1;
否则乘以prime[i]
φ(x)=x(x1pi),pix的素因子;
ans=φ(p)kpbi,bi为素数表中前p位的数;
当前的素因子出现过时乘以prime[i];
即: dp[i][j]={dp[i][j]+dp[i1][j]prime[j];idp[i][j]+dp[i1][j1](prime[j]1);i;

#include <iostream>#include <cstring>#include <cstdio>#define LL long long#define N 502#define M 4000#define MOD 1000000007using namespace std;bool not_prime[M];int prim[N*2];LL dp[N][N];void init(){    memset(not_prime, 0, sizeof(not_prime));    memset(dp, 0, sizeof(dp));    prim[1] = 0;    int cnt = 0;    for(int i = 2; i < M; i++)     {          if(!not_prime[i])         {               prim[++cnt] = i;            for(int j = i + i; j < M; j += i)            {                  not_prime[j] = 1;              }          }      }      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] * prim[j]) % MOD;            dp[i][j] = (dp[i][j] + dp[i-1][j-1] * (prim[j] - 1)) % MOD;        }    }}int main(){    init();    int T;    scanf("%d", &T);    for (int cas = 1; cas <= T; cas++)    {        int n, m;        scanf("%d%d", &n, &m);        printf("Case %d: %lld\n", cas, dp[n][m]);    }    return 0;}
0 0
原创粉丝点击