原问题可以转换为求 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;
}