题目大意
定义F(n)表示最小公倍数为n的二元组的数量。
即:如果存在两个数(二元组)X,Y(X <= Y),它们的最小公倍数为N,则F(n)的计数加1。
例如:F(6) = 5,因为[2,3] [1,6] [2,6] [3,6] [6,6]的最小公倍数等于6。
给出一个区间[a,b],求最小公倍数在这个区间的不同二元组的数量。
例如:a = 4,b = 6。符合条件的二元组包括:
[1,4] [2,4] [4,4] [1,5] [5,5] [2,3] [1,6] [2,6] [3,6] [6,6],共10组不同的组合。
解题思路
先不考虑偏序限制。
Ans=∑Nd=1∑N/dx=1∑N/dy=1[(dxy<=N)且((x,y)==1)]
Ans=∑Ni=1mu[i]∑Nd=1∑N/dx=1∑N/dy=1[(dxy<=N)且((x,y)==i)]
Ans=∑Ni=1mu[i]∑N/id=1∑N/d/ix=1∑N/d/iy=1[di2xy<=N]
观察可知i<=sqrt(N),发现d,x,y其实是等价的,我们可以强制他们满足偏序关系且互不相同,那d<=pow(N/i/i,1/3),x<=sqrt(N/i/i/d),y的取值范围可以直接算出来。
对于一对相同的,三个相同的可以类似算出。最后加上x==y的情况除以2就是答案。
code
:0;
}
}
Tmp=sqrt(Tm);
Fo(i,1,Tmp)Sum+=(Tm/i/i-(Tm/i/i>=i))*4;
Sum+=II*2;
Ans+=Mu[d]*Sum;
}
return Ans/2;
}
int main(){
freopen("d.in","r",stdin);
freopen("d.out","w ",stdout);
LL NN=sqrt(Mxn);
Mu[1]=1;
Fo(i,2,NN){
if(!Tag[i])Pri[++Pri[0]]=i,Mu[i]=-1;
Fo(j,1,Pri[0]){
if(i*Pri[j]>NN)break;
Tag[i*Pri[j]]=1;
Mu[i*Pri[j]]=-Mu[i];
if(i%Pri[j]==0){Mu[i*Pri[j]]=0;break;}
}
}
LL L,R;scanf("%lld%lld",&L,&R);
printf("%lld",Calc(R)-Calc(L-1));
return 0;
}