</pre><pre name="code" class="cpp">#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
long long T, A, B, N, kase;
vector<long long> GetPrimefun(long long n)
{
std::vector<long long> v;
for (long long i = 2; i * i <= n; i++)
if (n % i == 0)
{
v.push_back(i);
while (n % i == 0) n /= i;
}
if (n > 1) v.push_back(n);
return v;
}
long long solve(long long x, long long n)
{
std::vector<long long> v = GetPrimefun(n);
long long sum = 0, tmp, cnt;
for (long long i = 1; i < (1 << v.size()); i++)
{
tmp = 1, cnt = 0;
for (long long j = 0; j < v.size(); j++)
if (i & (1LL << j)) tmp *= v[j], cnt++;
sum += (cnt & 1 ? 1 : -1) * x / tmp;
}
return x - sum;
}
int main(int argc, char const *argv[])
{
scanf("%d", &T);
while (T--)
{
scanf("%lld%lld%lld", &A, &B, &N);
printf("Case #%lld: %lld\n", ++kase, solve(B, N) - solve(A - 1, N));
}
return 0;
}
求(a,b)区间与n互质的数的个数.即为求(1,m)区间于n互质的数的个数
但与欧拉函数不同,使用容斥原理。
先对n分解质因数,分别记录每个质因数, 那么所求区间内与某个质因数不互质的个数就是n / r(i),假设r(i)是r的某个质因子 假设只有三个质因子, 总的不互质的个数
为:p1+p2+p3-p1*p2-p1*p3-p2*p3+p1*p2*p3
当P的数量太多时,就需要用位运算表示了。