University of New Tmutarakan trains the first-class specialists in mental arithmetic. To enter the University you should master arithmetic perfectly. One of the entrance exams at the Divisibility Department is the following. Examinees are asked to find K different numbers that have a common divisor greater than 1. All numbers in each set should not exceed a given number S. The numbers K and S are announced at the beginning of the exam. To exclude copying (the Department is the most prestigious in the town!) each set of numbers is credited only once (to the person who submitted it first).
Last year these numbers were K=25 and S=49 and, unfortunately, nobody passed the exam. Moreover, it was proved later by the best minds of the Department that there do not exist sets of numbers with the required properties. To avoid embarrassment this year, the dean asked for your help. You should find the number of sets of K different numbers, each of the numbers not exceeding S, which have a common divisor greater than 1. Of course, the number of such sets equals the maximal possible number of new students of the Department.
Input
The input contains numbers K and S (2 ≤ K ≤ S ≤ 50).
Output
You should output the maximal possible number of the Department’s new students if this number does not exceed 10000 which is the maximal capacity of the Department, otherwise you should output 10000.
Example
input output
3 10
11
这个题就是把所有因数里有素数的求出来
然后就容斥那些因子有合数的
组合数打表还不是美滋滋?
#include<bits/stdc++.h>
using namespace std;
unsigned long long sus[16]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
const unsigned long long maxn=51;
long long c[maxn][maxn];
void cinit()
{
for(unsigned long long i=0; i<maxn; i++)
{
c[i][0]=c[i][i]=1;
for(unsigned long long j=1; j<i; j++)
c[i][j]=(c[i-1][j]+c[i-1][j-1]);
}
}
unsigned long long susu=0;unsigned long long n,m;
unsigned long long dfs(unsigned long long mulu,unsigned long long beichu,unsigned long long chu)
{
if(mulu>susu)return 0;
unsigned long long daan=0;
for(unsigned long long a=mulu;a<=susu;a++)
{
daan+=c[m/(sus[a]*chu)][n]-dfs(a+1,m,sus[a]*chu);
}
return daan;
}
main()
{
cinit();
while(cin>>n>>m)
{
for(unsigned long long a=1;a<=15;a++)
{
if(sus[a]>m)break;
susu=max(susu,a);
}
unsigned long long daan=0;
for(unsigned long long a=1;a<=susu;a++)
{
daan+=c[m/sus[a]][n]-dfs(a+1,m,sus[a]);
}
cout<<(daan>10000?10000:daan)<<endl;
}
}