题意
求
N
以内的大小为
题解
设f[x]表示公约数是x的倍数的情况数,g[x]表示公约数恰好是x的情况数
有:
fn=∑n|dg(d)
gn=∑n|df(d)∗μ(dn)
其中
fn=(⌊Nd⌋k)
故
gn=∑2≤n≤N∑n|d(⌊Nd⌋k)μ(dn)
交换后
gn=∑d(⌊Nd⌋k)∑n|dμ(dn)[n≥2]
注意到二项式系数当 d≥N 时为 0 ,故
即
gn=∑2≤d≤N(⌊Nd⌋k)
code
#include<cstdio>
#include<cstring>
typedef long long LL;
const int maxn=1010;
const int maxp=1010;
int prime[maxp],primeN;
int phi[maxn], mu[maxn];
LL sphi[maxn];int smu[maxn];
bool isprime[maxn];
void gen(int n) {
primeN = 0;
memset(isprime, 1, sizeof isprime);
isprime[0]=isprime[1]=0;
phi[1]=1, mu[1]=1;
for(int i=2,p;i<n;++i){
if (isprime[i]) {
prime[primeN ++]=p=i;
phi[p]=p-1, mu[p]=-1;
}
for(int j=0,x;j<primeN && (x=i*(p=prime[j]))<n;++j){
isprime[x] = 0;
if(!(i%p)){
phi[x]=phi[i]*p, mu[x]=0;
break;
} else {
phi[x]=phi[i]*(p-1), mu[x]=-mu[i];
}
}
}
}
const int MAXN=60;
int K,N;
LL C[MAXN][MAXN];
int main(){
// freopen("in.txt","r",stdin);
scanf("%d%d",&K,&N);
gen(N+1);
for(int i=0;i<=N;++i){
C[i][0]=C[i][i]=1;
for(int j=1;j<i;++j)
C[i][j]=C[i-1][j]+C[i-1][j-1];
}
LL res=0;
for(int d=1;d<=N;++d)
res+=C[N/d][K]*((d==1) - mu[d]);
/* for(int n=2;n<=N;++n)
for(int d=n;d<=N;++d)if(d%n==0)
res+=C[N/d][K]*mu[d/n];
*/
printf("%d\n",res<=10000 ? res : 10000);
// for(;;);
return 0;
}