点开POJ,看到一道中文题,就点开看了看,发现这题我好像不会

参考了这篇博客:https://blog.csdn.net/ac_gibson/article/details/46531229

对于跳蚤来说,需要选出一组整数x1,x2,x3......xn满足a1*x1+a2*x2+a3*x3+...+an*xn=1,其中an=m

而这个方程有解的充要条件就是a1,a2,a3......an互质

正难则反,我们考虑有多少是不满足互质的,将m质因数分解,枚举素因子,利用容斥完成这道题

(之前也不会这种容斥的写法,想了想觉得很有道理)

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=200;
int n,m;
int p[N],tot,d[N];
ll ans;
ll qpow(ll x,ll y)
{
  ll ret=1;
  while(y)
    {
      if(y&1) ret=ret*x;
      x=x*x;
      y>>=1;
    }
  return ret;
}
void div(int x)
{
  /*
  int t=2;
  while(x!=1)
    {
      if(x%t==0) p[++tot]=t;
      while(x%t==0) x/=t;
      t++;
    }*/
  // for(int i=1;i<=tot;i++) printf("%d%c",p[i],"*\n"[i==tot]);
  for(int i=2;i*i<=x;i++)
    {
      if(x%i==0)p[++tot]=i,x/=i;
      while(x%i==0) x/=i;
    }
  if(x>1) p[++tot]=x;
}
ll qaq;
void dfs(int st,int dep,int up)
{
  if(dep==up+1)
    {
      int x=m;
      for(int i=1;i<=up;i++) x/=d[i];
      qaq+=qpow(x,n);
      return ;
    }
  for(int i=st;i<=tot;i++)
    {
      d[dep]=p[i];
      dfs(i+1,dep+1,up);
    }
}
int main()
{
  while(~scanf("%d%d",&n,&m))
    {
      tot=0;ans=0;
      div(m);
      for(int i=1;i<=tot;i++)
    {
      qaq=0;
      dfs(1,1,i);
      if(i&1) ans+=qaq;
      else ans-=qaq;
    }
      printf("%lld\n",qpow(m,n)-ans);
    }
  return 0;
}