题目链接:https://codeforces.com/problemset/problem/439/E
反演后求方程整数解的个数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 200010;
const int M = 1000000007;
int q, n, f;
int fac[maxn], ifac[maxn];
int cnt;
int prime[100010], mu[100010], is_prime[100010];
int qsm(int i, int po){
int res = 1;
while(po){
if(po & 1) res = 1ll * i * res % M;
i = 1ll * i * i % M;
po >>= 1;
}
return res;
}
int C(int x, int y){
if(y > x) return 0;
return 1ll * fac[x] * ifac[y] % M * ifac[x-y] % M;
}
ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
int main(){
fac[0] = 1;
for(int i = 1 ; i <= 100000 ; ++i) fac[i] = 1ll * fac[i-1] * i % M;
ifac[100000] = qsm(fac[100000], M-2);
for(int i = 99999 ; i >= 0 ; --i) ifac[i] = 1ll * ifac[i+1] * (i+1) % M;
mu[1] = 1;
for(int i = 2; i <= 100000; ++i){
if(!is_prime[i]){
prime[++cnt] = i;
mu[i] = -1;
}
for(int j = 1 ; j <= cnt && prime[j] * i <= 100000 ; ++j){
is_prime[i * prime[j]] = 1;
if(i % prime[j] == 0) {
mu[i * prime[j]] = 0;
break;
} else {
mu[i * prime[j]] = -mu[i];
}
}
}
q = read();
for(int i = 1 ; i <= q ; ++i){
n = read(), f = read();
int ans = 0;
for(int j = 1 ; j <= (int)sqrt(n+0.5) ; ++j){
if(n % j == 0){
if(j * f <= n) ans = ((ans + 1ll * mu[j] * C(n/j-1, f-1) % M) % M + M) % M;
if(j * j != n){
if(n/j * f <= n) ans = ((ans + 1ll * mu[n/j] * C(j-1, f-1) % M) % M + M) % M;
}
}
}
printf("%d
", ans);
}
return 0;
}