1159: One Theorem, One Year
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 16 Solved: 9
[ Submit][ Status][ Web Board]
Description
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 anAlmost-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
Sample Output
HINT
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.
Source
#include<stdio.h>
#include<string.h>
typedef long long lld;
int n,m;
const int maxn=5000;
const lld mod=1000000007;
int flag[maxn];
int prime[maxn];
int cnt;
lld dp[505][505];
lld map[505][505];
lld Mul(lld a,lld b)
{
lld ret=1;
while(b)
{
if(b&1)ret=ret*a%mod;
b>>=1;
a=a*a%mod;
}
return ret;
}
void Init()
{
int i, j;
cnt=1;
memset(flag,0,sizeof(flag));
for(i=2;i<maxn;i++)
if(!flag[i])
{
prime[cnt++]=i;
for(j=i*2;j<maxn;j+=i)
flag[j]=1;
}
}
void Gao()
{
lld i,j,k;
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(i=1;i<=500;i++)
for(j=1;j<=500;j++)
map[i][j]=Mul(prime[i],j-1);//Mul(prime[i],k-1)
for(i=1;i<=500;i++)
for(j=i-1;j<=500;j++)
for(k=1;k<=500-j;k++)
{
dp[i][j+k]+=(dp[i-1][j]*map[i][k]%mod)*(prime[i]-1);
if(dp[i][j+k]>=mod) dp[i][j+k]%=mod;
}
}
int main()
{
int T;
int cas=1;
scanf("%d",&T);
Init();
Gao();
while(T--)
{
scanf("%d%d",&n,&m);
printf("Case %d: %lld\n",cas++,dp[m][n]);
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long dp[510][510];
long long pri[40010],a[40010];
void prime()
{
memset(a,0,sizeof(a));
int i,j;
for(i=2;i<=200;i++)
if(!a[i])
for(j=i*i;j<=40000;j+=i)
a[j]=1;
for(i=0,j=2;j<=40000;j++)
if(!a[j]) pri[++i]=j;
}
long long mod=1000000007;
int main()
{
int t;
scanf("%d",&t);
prime();
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=500;i++){
dp[i][0]=1;
long long sum=0,tmp=1;
for(int j=1;j<=500;j++){
sum=(pri[i]*sum+dp[i-1][j-1]*pri[i])%mod;
dp[i][j]=(dp[i-1][j]+sum)%mod;
/*
long long tmp=1;
for(int k=1;k<=j;k++){
tmp*=pri[i];
tmp%=mod;
dp[i][j]=(dp[i][j]+dp[i-1][j-k]*tmp)%mod;
}
*/
}
}
for(int p=1;p<=t;p++){
int n,m;
scanf("%d%d",&n,&m);
long long ans=1;
for(int i=1;i<=m;i++)
ans=ans*(pri[i]-1)%mod;
ans=ans*dp[m][n-m]%mod;
printf("Case %d: %lld\n",p,ans);
}
return 0;
}