原问题可以转换为求 x(1)*a(1)+x(2)*a(2)+....x(n+1)*a(n+1)=1 的x(i)的所有组合
【其中x(n+1)=M】
若gcd (x1,x2,x3....M)=1,则我们知道此式一定有解(扩展欧几里得知识),即我们要求一组x,使得它们
和M的最大公约数为1,从反面考虑,我们可用总数减去最大公约数不为1的。
即x(1~n)与M存在公因子,至此容斥的思想就出现了。
解:求出M的所有公因子p1,p2,p3......
若 x(1~n) 与M公因子为p1,则个数为(M/p1)^n
若 ……………………为p2, 则个数为(M/p2)^n
若 ……………………为p1*p2, 则个数为(M/(p1*p2))^n
容斥用dfs实现就好。
#include <iostream> using namespace std; typedef long long ll; ll n,m,ans,pri[100]; int top; ll ppow(ll n,ll m) { return n?ppow(n-1,m)*m:1; } void dfs(int p,ll num,int flag) { if(p>-1) ans+=flag*ppow(n,m/num); for(int i=p+1;i<top;i++) { dfs(i,num*pri[i],-flag); } } int main() { while(cin>>n>>m) { top=0; ll t=m; for(int i=2;i*i<=t;i++) { if(t%i==0) { pri[top++]=i; while(t%i==0) t/=i; } }if(t>1) pri[top++]=t; ans=ppow(n,m); dfs(-1,1,1); cout<<ans<<endl; } return 0; }