https://cn.vjudge.net/contest/243561#problem/F
首先我们要会求1~m中与n不互质的数的个数。然后用b-(a-1)-(solve(b)-solve(a-1))即可。solve(b)是指1~b中与n不互质的数的个数。不互质就说明有公共的质因子。
那么solve(b)怎么求呢?先把n的质因子全都筛出来存在一个vector数组里,然后用容斥原理求即可。
因为如果单把有和n的质因子相同的质因子的数算上的话,会有许多重复计算(比如一个数的质因子有3的同时也可能有5),因此我们把有奇数个相同质因子的算作正项,偶数个质因子的算作负项(容斥原理)。比如在1~a中有x个数是3的倍数,y个数是5的倍数,z个数同时是3和5的倍数,那么x和y就加上,z就减去。
怎么枚举质因子的集合呢?我们用二进制来表示一个状态,这个状态代表了n中的某些质因子的组合。如果质因子的个数是奇数的话就作为正项,否则就是负项。用t表示这些质因子的乘积,1~b中有b/t个数是t的倍数。
#include
using namespace std;
int num, y[1000000];
__int64 a,b,n;
void run(int x) //分解质因子
{
num=0;
for (int i=2; i*i<=x; i++)
{
if (x % i==0)
{
y[num++]=i;
while (x % i==0)
x=x/i;
}
}
if (x>1)
y[num++]=x;
}
int solve(__int64 x)
{
int p;
__int64 t,ans=0;
for (__int64 i=1; i<(__int64)(1<