Insert n Sweets into an F-1 baffle and divide them into f points (a1, a2, a3... af ). Ask how many methods can make gcd (a1, a2, a3... af) = 1;
Solution; Mobius, first by 1 as the unit, this time there are C (n-1, F-1), and then remove gcd is not 1. At this time, it is required that if the number of quality factors is an odd number, then subtract (mou value is-1), and even numbers are added (mou value is + 1 ), then the mou value of the number of arguments is 0. In this way, we have been able to reprimand. Note that only the number of n-grams is used for calculation. If n-grams are not used, this factor will not appear in gcd.
Code:
/******************************************************* author:xiefubao*******************************************************/#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <vector>#include <algorithm>#include <cmath>#include <map>#include <set>#include <stack>#include <string.h>//freopen ("in.txt" , "r" , stdin);using namespace std;#define eps 1e-8#define zero(_) (abs(_)<=eps)const double pi=acos(-1.0);typedef long long LL;const int Max=100010;const int INF=1000000007;int mou[Max];LL fac[Max];map<pair<int,int>,LL> maps;int n,f;LL pow(LL a,int b){ LL ans=1; while(b) { if(b&1) ans=(ans*a)%INF; a=(a*a)%INF; b>>=1; } return ans;}LL getreverse(LL lo){ return pow(lo,INF-2);}void init(){ for(LL i=2; i<Max; i++) if(!mou[i]) { mou[i]=i; for(LL j=i*i; j<Max; j+=i) mou[j]=i; // cout<<i<<" "; } mou[1]=1; for(int i=2; i<Max; i++) { if((i/mou[i])%mou[i]==0) mou[i]=0; else mou[i]=-mou[i/mou[i]]; } fac[0]=1; for(int i=1; i<Max; i++) fac[i]=(fac[i-1]*i)%INF;}LL C(int a,int b){ LL ans=fac[a]; ans=(ans*getreverse(fac[a-b])%INF*getreverse(fac[b]))%INF; return ans;}int main(){ int t; cin>>t; init(); while(t--) { scanf("%d%d",&n,&f); if(maps.find(pair<int,int>(n,f))!=maps.end()) { printf("%I64d\n",maps[pair<int,int>(n,f)]); continue; } LL ans=0; for(int i=1; i<=n/f; i++) { if((n%i)!=0)continue; ans+=C(n/i-1,f-1)*mou[i]; if(ans>=INF) ans-=INF; if(ans<0) ans+=INF; } printf("%I64d\n",ans); maps[pair<int,int>(n,f)]=ans; } return 0;}