D. Easy Math
Given a positive integers nn , Mobius function \mu(n)μ(n) is defined as follows:
\displaystyle \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, \cdots, k)pi(i=1,2,⋯,k) are different prime numbers.
Given two integers mm, nn, please calculate \sum_{i = 1}^{m} \mu(in)∑i=1mμ(in).
Input
One line includes two integers m (1 \le m \le 2e9)m(1≤m≤2e9), n (1 \le n \le 1e12)n(1≤n≤1e12) .
Output
One line includes the answer .
样例输入
2 2
样例输出
-1
题意:
已知,求
思路:
不需要递归,更不需要容斥!直接将min_25修改一下即可,20ms
Min_25筛:https://blog.csdn.net/Jaihk662/article/details/82024131
可以分析出这题的递推公式就是:
答案就是
其中T表示大于等于第y个质数且小于m且不是n的因子的质数个数,右边的求和中不能为n的因子
复杂度约为O()
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
LL cnt, Cnt, id[1000005], B, m, H[1000005], jud[1000005], Ans, n, w[1000005], pri[1000005], Pri[100005];
bool flag[1000005];
void Primeset(LL n)
{
LL i, j;
for(i=2;i<=n;i++)
{
if(flag[i]==0)
pri[++cnt] = i;
for(j=1;j<=cnt&&i*pri[j]<=n;j++)
{
flag[i*pri[j]] = 1;
if(i%pri[j]==0)
break;
}
}
}
LL F(LL x, LL y)
{
LL i, k, ans;
if(x<=1 || pri[y]>x)
return 0;
if(x>B)
k = n/x;
if(x<=B)
k = id[x];
ans = (y-1)-H[k];
for(i=1;i<=Cnt;i++)
{
if(Pri[i]>pri[y-1] && Pri[i]<=w[k])
ans++;
}
for(i=y;i<=cnt&&(LL)pri[i]*pri[i]<=x;i++)
{
if(jud[i]==0)
ans = ans-F(x/pri[i], i+1);
}
return ans;
}
int main(void)
{
LL i, j, k, P, last, sum;
scanf("%lld%lld", &n, &P);
B = sqrt(n), Primeset(1000002);
sum = 0;
for(i=1;i<=cnt&&pri[i]*pri[i]<=P;i++)
{
if(P%(pri[i]*pri[i])==0)
{
printf("0\n");
return 0;
}
if(P%pri[i]==0)
{
jud[i] = 1;
Pri[++Cnt] = pri[i], sum++;
P /= pri[i];
}
}
if(P!=1)
{
Pri[++Cnt] = P, sum++;
for(i=1;i<=cnt;i++)
{
if(pri[i]==P)
jud[i] = 1;
}
}
for(i=1;i<=n;i=last+1)
{
w[++m] = n/i;
H[m] = w[m]-1;
last = n/(n/i);
if(n/i<=B)
id[n/i] = m;
}
for(j=1;j<=cnt;j++)
{
for(i=1;i<=m&&pri[j]*pri[j]<=w[i];i++)
{
if(w[i]/pri[j]<=B)
k = id[w[i]/pri[j]];
else
k = n/(w[i]/pri[j]);
H[i] = H[i]-(H[k]-(j-1));
}
}
Ans = F(n, 1)+1;
if(Cnt%2==1)
Ans *= -1;
printf("%lld\n", Ans);
return 0;
}