CF1036F Relatively Prime Powers
题目大意
对于一个数 ,当且仅当将其分解后各个质因数的指数的最大公约数为 时,我们称这个数是合法的。
有 组数据,对于每组数据,询问区间 中合法的数的个数。
。
解题思路
一个数不是合法的,也就是这个 。
此时这个数字一定可以被写成 。
问题就变成 中有多少个数能被表示成 ,其中 。
考虑莫比乌斯反演。
设 表示 的数的个数。
设 表示 的数的个数。
显然,。
根据莫比乌斯反演,我们有 。
然后,。
那么 。
注意精度问题即可。
CODE
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 100, M = 6e3;
ll prime[N], mu[N], cnt;
bool isprime[N];
ll read()
{
ll x = 0, f = 1;
char c = getchar();
while (!isdigit(c))
{
if (c == '-')
f = -1;
c = getchar();
}
while (isdigit(c))
x = x * 10 + c - '0', c = getchar();
return x * f;
}
inline void js(int n)
{
mu[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!isprime[i])
prime[++cnt] = i, mu[i] = -1;
for (int j = 1; j <= cnt && i * prime[j] <= n; j++)
{
isprime[i * prime[j]] = 1;
if (i % prime[j] == 0)
break;
mu[i * prime[j]] = -mu[i];
}
}
}
#define double long double
ll n;
double qpow(double a, ll b)
{
if (b == 1)
return a;
if (b % 2 == 1)
return qpow(a, b - 1) * a;
double temp = pow(a, b / 2);
return temp * temp;
}
void solve()
{
n = read();
ll ans = 0;
for (int i = 1; i <= 60; i++)
{
ll temp = (ll)(pow(n, 1.l / i)) + 1;
while (qpow(temp, i) > n)
temp--;
ans += mu[i] * (temp - 1);
}
printf("%lld\n", ans);
}
signed main()
{
int t = read();
js(100);
while (t--)
solve();
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18122073