zoukankan      html  css  js  c++  java
  • 1298

    1298 - One Theorem, One Year
    Time Limit: 2 second(s) Memory Limit: 32 MB

    A number is Almost-K-Prime if it has exactly K prime numbers (not necessarily distinct) in its prime factorization. For example, 12 = 2 * 2 * 3 is an Almost-3-Prime and 32 = 2 * 2 * 2 * 2 * 2 is an Almost-5-Prime number. A number X is called Almost-K-First-P-Prime if it satisfies the following criterions:

    1. X is an Almost-K-Prime and
    2. X has all and only the first P (P ≤ K) primes in its prime factorization.

    For example, if K=3 and P=2, the numbers 18 = 2 * 3 * 3 and 12 = 2 * 2 * 3 satisfy the above criterions. And 630 = 2 * 3 * 3 * 5 * 7 is an example of Almost-5-First-4-Pime.

    For a given K and P, your task is to calculate the summation of Φ(X) for all integers X such that X is an Almost-K-First-P-Prime.

    Input

    Input starts with an integer T (≤ 10000), denoting the number of test cases.

    Each case starts with a line containing two integers K (1 ≤ K ≤ 500) and P (1 ≤ P ≤ K).

    Output

    For each case, print the case number and the result modulo 1000000007.

    Sample Input

    Output for Sample Input

    3

    3 2

    5 4

    99 45

    Case 1: 10

    Case 2: 816

    Case 3: 49939643

    Note

    1. In mathematics Φ(X) means the number of relatively prime numbers with respect to X which are smaller than X. Two numbers are relatively prime if their GCD (Greatest Common Divisor) is 1. For example, Φ(12) = 4, because the numbers that are relatively prime to 12 are: 1, 5, 7, 11.
    2. For the first case, K = 3 and P = 2 we have only two such numbers which are Almost-3-First-2-Prime, 18=2*3*3 and 12=2*2*3. The result is therefore, Φ(12) + Φ(18) = 10.

    Problem Setter: Samir Ahmed
    Special Thanks: Jane Alam Jan
    思路:DP;状态转移方程dp[i][j]=dp[i-1][j-1]+dp[i][j-1];i表示前i个素数,j表示由前i个素数构成数的素数因子的长度,dp[i][j]存的是符合这个要求的所有数的和;
    状态解释:当前末尾的数放的是第i个素数,那么它的前一个数放的是它的前一个素数或者是他本身。
    所以dp先打个表,再根据欧拉函数n*((1-1/p1)*(1-1/p2).....);因为dp[i][j]是那些素因子都相同数的和,再将(p1*p2*....)的表打好an,把(p1-1)*(p2-1)*....bn打好
    所以K=i,P=j;求的直就为dp[j][i]*(an[j]/bn[j])%mod;然后把bn[i]用费马小定理转换成逆元所以最后就为dp[j][i]*(an[j]*bn[j])%mod。
     1 #include<math.h>
     2 #include<stdlib.h>
     3 #include<stdio.h>
     4 #include <algorithm>
     5 #include<iostream>
     6 #include<string.h>
     7 #include<vector>
     8 #include<map>
     9 #include<math.h>
    10 using namespace std;
    11 typedef  long long LL;
    12 typedef unsigned long long ll;
    13 bool prime[5000]= {0};
    14 int su[600];
    15 LL  dp[600][600];
    16 LL ola[600];
    17 LL ola1[600];
    18 const LL mod=1e9+7;
    19 LL quick(int n,int m);
    20 int main(void)
    21 {
    22         int i,j,k,p,q;
    23         for(i=2; i<=100; i++)
    24         {
    25                 for(j=i; i*j<=5000; j++)
    26                 {
    27                         prime[i*j]=true;
    28                 }
    29         }
    30         int ans=1;
    31         for(i=2; i<=5000; i++)
    32         {
    33                 if(!prime[i])
    34                 {
    35                         su[ans++]=i;
    36                 }
    37         }
    38         memset(dp,0,sizeof(dp));
    39         dp[0][0]=1;
    40         dp[1][1]=2;
    41         for(i=1; i<=500; i++)
    42         {
    43                 for(j=i; j<=500; j++)
    44                 {
    45                         dp[i][j]=(((dp[i][j-1]+dp[i-1][j-1])%mod)*(su[i]))%mod;
    46                 }
    47         }
    48         ola[1]=su[1];
    49         ola1[1]=su[1]-1;
    50         for(i=2; i<=500; i++)
    51         {
    52                 ola[i]=(su[i]*ola[i-1])%mod;
    53                 ola1[i]=(su[i]-1)*ola1[i-1]%mod;
    54         }
    55         for(i=1; i<=500; i++)
    56         {
    57                 ola[i]=quick(ola[i],mod-2);
    58         }
    59         scanf("%d",&k);
    60         int s;
    61         for(s=1; s<=k; s++)
    62         {
    63                 scanf("%d %d",&p,&q);
    64                 LL cnt=dp[q][p];
    65                 LL cns=ola[q];
    66                 LL bns=ola1[q];
    67                 LL sum=((cnt*cns)%mod*bns)%mod;
    68                 printf("Case %d: ",s);
    69                 printf("%lld
    ",sum);
    70         }
    71         return 0;
    72 }
    73 LL quick(int n,int m)
    74 {
    75         LL ans=1;
    76         LL N=n;
    77         while(m)
    78         {
    79                 if(m&1)
    80                 {
    81                         ans=(ans*N)%mod;
    82                 }
    83                 N=(N*N)%mod;
    84                 m/=2;
    85         }
    86         return ans;
    87 }
    油!油!you@
  • 相关阅读:
    go 从入门到精通(二)基本数据类型和操作符
    python爬虫番外篇(一)进程,线程的初步了解
    Go从入门到精通(一)go语言初识
    python爬虫从入门到放弃(九)之 实例爬取上海高级人民法院网开庭公告数据
    python爬虫从入门到放弃(八)之 Selenium库的使用
    python爬虫从入门到放弃(七)之 PyQuery库的使用
    python爬虫从入门到放弃(六)之 BeautifulSoup库的使用
    python爬虫从入门到放弃(五)之 正则的基本使用
    python爬虫从入门到放弃(三)之 Urllib库的基本使用
    openstack网络基本概念(转)
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5377408.html
Copyright © 2011-2022 走看看