Given a positive integers nnn , Mobius function μ ( n ) \mu(n) μ(n) is defined as follows:
μ ( n ) = { 1 n = 1 ( − 1 ) k n = p 1 p 2 ⋯ p k 0 o t h e r \mu(n) = \begin{cases} 1 &n = 1 \\ (-1)^k & n = p_1p_2\cdots p_k \\ 0 &other \end{cases} μ(n)=⎩⎪⎨⎪⎧1(−1)k0n=1n=p1p2⋯pkother
p i ( i = 1 , 2 , ⋯ , k ) p i ( i = 1 , 2 , ⋯   , k ) pi(i=1,2,⋯,k)p_i (i = 1, 2, \cdots, k) pi(i=1,2,⋯,k)pi(i=1,2,⋯,k)are different prime numbers.
Given two integers mmm, nnn, please calculate ∑ i = 1 m μ ( i n ) \sum_{i = 1}^{m}\mu(in) ∑i=1mμ(in) .
Input
One line includes two integers m(1≤m≤2e9)m (1 \le m \le 2e9)m(1≤m≤2e9), n(1≤n≤1e12)n (1 \le n \le 1e12)n(1≤n≤1e12) .
Output
One line includes the answer .
样例输入 复制
2 2
样例输出 复制
-1
给你n和m求解 ∑ i = 1 m μ ( i n ) \sum_{i=1}^m\mu(in) i=1∑mμ(in)其中 μ \mu μ为莫比乌斯函数
先考虑n为含有平方因子的情况会发现,每一个i*n之后 μ ( i n ) \mu(in) μ(in)都会为0,所以特判一下
再考虑n不含有平方因子,那么n一定可以拆成 n = p 1 p 2 p 3 p 4 ⋯ p i n=p_1p_2p_3p_4\cdots p_i n=p1p2p3p4⋯pi
我们令 S ( m , n ) = ∑ i = 1 m μ ( i n ) S(m,n)=\sum_{i=1}^m\mu(in) S(m,n)=i=1∑mμ(in)然后现在考虑 n n n的一个素因子 d d d, d d d可以是 n n n的任意一个素因子,那么肯定有 n d \frac{n}{d} dn和 d d d互质,我们将n分解
∑ i = 1 m μ ( i n ) = ∑ i = 1 m μ ( i ⋅ n d ⋅ d ) \sum_{i=1}^m\mu(in)=\sum_{i=1}^m\mu\left ( i\cdot \frac{n}{d}\cdot d \right ) i=1∑mμ(in)=i=1∑mμ(i⋅dn⋅d)
其中 d d d和 n d \frac{n}{d} dn一定是互质的,那么剩下就是考虑 d d d和 i i i的关系
[ 1 , m ] [1,m] [1,m]中的数和 d d d只会有两种可能互质和不互质的,由于 μ ( ) \mu() μ()为积性函数,那么若 i i i与 d d d互质就会有 μ ( i ⋅ n d ⋅ d ) = μ ( i ⋅ n d ) μ ( d ) \mu\left ( i\cdot \frac{n}{d}\cdot d \right )=\mu\left ( i\cdot \frac{n}{d} \right )\mu\left (d \right ) μ(i⋅dn⋅d)=μ(i⋅dn)μ(d)
∑ i = 1 m μ ( i ⋅ n d ⋅ d ) \sum_{i=1}^m\mu\left ( i\cdot \frac{n}{d}\cdot d \right ) i=1∑mμ(i⋅dn⋅d)
∑ i = 1 m μ ( i ⋅ n d ) μ ( d ) = − ∑ i = 1 m μ ( i ⋅ n d ) \sum_{i=1}^m\mu\left ( i\cdot \frac{n}{d} \right )\mu\left (d \right )=-\sum_{i=1}^m\mu\left ( i\cdot \frac{n}{d} \right ) i=1∑mμ(i⋅dn)μ(d)=−i=1∑mμ(i⋅dn)
由于 μ ( d ) \mu(d) μ(d)为单素数他的值肯定为 − 1 -1 −1,思考这个式子与原式的关系,会发现实际上多减了一个 i i i与 d d d不互质的部分,那我们给他加回去 i i i与 d d d不互质的部分就可以了,那现在考虑一下 [ 1 , m ] [1,m] [1,m]中与素数 d d d不互质的数是那些,就是 [ 1 , m ] [1,m] [1,m]中 d d d的倍数,只要从1枚举到 m d \frac{m}{d} dm就可以了
∑ i = 1 m d μ ( i ⋅ d ⋅ n d ) = ∑ i = 1 m d μ ( i n ) \sum_{i=1}^{\frac{m}{d}}\mu(i\cdot d\cdot \frac{n}{d})=\sum_{i=1}^{\frac{m}{d}}\mu(in) i=1∑dmμ(i⋅d⋅dn)=i=1∑dmμ(in)就好了,总结一下就是
∑ i = 1 m μ ( i n ) = − ∑ i = 1 m μ ( i ⋅ n d ) + ∑ i = 1 m d μ ( i n ) \sum_{i=1}^m\mu(in)=-\sum_{i=1}^m\mu\left ( i\cdot \frac{n}{d} \right )+\sum_{i=1}^{\frac{m}{d}}\mu(in) i=1∑mμ(in)=−i=1∑mμ(i⋅dn)+i=1∑dmμ(in)
也就是
S ( m , n ) = − S ( m , n d ) + S ( m d , n ) S(m,n)=-S(m,\frac{n}{d})+S(\frac{m}{d},n) S(m,n)=−S(m,dn)+S(dm,n)
有了这个递归方程,我们每次只要找到当前的n的一个素因子就可以递归下去了,递归到 S ( 0 , n ) = 0 和 S ( m , 1 ) S(0,n)=0和S(m,1) S(0,n)=0和S(m,1)
S ( m , 1 ) = ∑ i = 1 m μ ( i ) S(m,1)=\sum_{i=1}^m\mu(i) S(m,1)=i=1∑mμ(i)
由于m还是比较大,所以我们得用杜教筛来求莫比乌斯函数的前缀和,杜教筛可以在 O ( n 2 3 ) O(n^{\frac{2}{3}}) O(n32)求出前缀和
这类积性函数的n倍(n为非平方因子数)求和的都有类似的式子若 f ( i ) f(i) f(i)为积性函数则有
∑ i = 1 m f ( i n ) = f ( d ) ∑ i = 1 m f ( i ⋅ n d ) + ∑ i = 1 m d f ( i n ) \sum_{i=1}^mf(in)=f(d)\sum_{i=1}^mf\left ( i\cdot \frac{n}{d} \right )+\sum_{i=1}^{\frac{m}{d}}f(in) i=1∑mf(in)=f(d)i=1∑mf(i⋅dn)+i=1∑dmf(in)
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn=10000000;
long long prime[1000000],num;
int vst[maxn+5],miu[maxn+5],mu_n;
inline void Pre()
{
miu[1]=1;
for (int i=2; i<=maxn; i++)
{
if (!vst[i]) prime[++num]=i,miu[i]=-1;
for (int j=1; j<=num && (ll)i*prime[j]<=maxn; j++)
{
vst[i*prime[j]]=1;
if (i%prime[j]==0)
{
miu[i*prime[j]]=0;
break;
}
miu[i*prime[j]]=miu[i]*miu[prime[j]];
}
}
for (int i=1; i<=maxn; i++) miu[i]+=miu[i-1];
}
unordered_map S;
inline int Sum(ll n)
{
if (n<=maxn) return miu[n];
if (S.find(n)!=S.end()) return S[n];
int tem=1;
ll l,r;
for (l=2; l*l<=n; l++) tem-=Sum(n/l);
for (ll t=n/l; l<=n; l=r+1,t--)
{
r=n/t;
tem-=(r-l+1)*Sum(t);
}
return S[n]=tem;
}
long long f(long long m,long long n)
{
if(m==0) return 0;
if(n==1) return Sum(m);
int flag=1;
for(int i=1; prime[i]*prime[i]<=n; i++)
{
if(n%prime[i]==0)
{
flag=0;
return -f(m,n/prime[i])+f(m/prime[i],n);
}
}
if(flag)
{
return -f(m,n/n)+f(m/n,n);
}
}
int judge(long long n)
{
for(int i=1; prime[i]*prime[i]<=n; i++)
{
if(n%prime[i]==0)
{
int cnt=0;
while(n%prime[i]==0)
{
n/=prime[i];
cnt++;
}
if(cnt>=2)
{
return 0;
}
}
}
return 1;
}
int main()
{
Pre();
long long m,n;
scanf("%lld%lld",&m,&n);
if(!judge(n))
{
printf("0\n");
return 0;
}
long long ans=f(m,n);
printf("%lld\n",ans);
return 0;
}