题意
- 给定 a , b \rm{a,b} a,b,求有多少对 i ≤ j \rm{i\le j} i≤j满足 l c m ( i , j ) ∈ [ a , b ] \rm{lcm(i,j)\in[a,b]} lcm(i,j)∈[a,b]( a ≤ b ≤ 1 0 11 ) \rm{a\le b\le 10^{11}}) a≤b≤1011)。
参考了ww3113306的这篇博客。
其实也比较套路,枚举 g c d \mathtt{gcd} gcd后反演就转化成了求有多少个三元组满足 a b c ≤ n \mathtt{abc\le n} abc≤n的问题,这个问题也很简单,强制给 a , b , c \tt{a,b,c} a,b,c定下大小关系,暴力枚举可以做到 O ( n 2 3 ) \tt{O(n^{\frac 2 3})} O(n32)的复杂度。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=sqrt(1e11)+9;
int notp[maxn],prime[maxn],mui[maxn],cnt;
void Get_Prime(int n)
{
notp[0]=notp[1]=1,mui[1]=1;
for(int i=2;i<=n;++i)
{
if(!notp[i]) prime[++cnt]=i,mui[i]=-1;
for(int j=1;j<=cnt&&prime[j]*i<=n;++j)
{
notp[prime[j]*i]=1;
if(i%prime[j]==0) break;
mui[prime[j]*i]=-mui[i];
}
}
}
ll h(ll n)
{
ll res=0;
for(ll i=1;i*i*i<=n;++i,++res)
for(ll j=i+1;j<n/(i*j);++j)
res+=(n/(i*j)-j)*6;
for(ll i=1;i<n/(i*i);++i)
res+=(n/(i*i)-i)*3;
for(ll i=1;i*i*i<=n&&i<sqrt(n/i);++i)
res+=((ll)sqrt(n/i)-i)*3;
return res;
}
ll f(ll n)
{
ll res=0;
for(ll i=1;i*i<=n;++i)
res+=mui[i]*h(n/(i*i));
return (res+n)>>1;
}
int main()
{
freopen("1222.in","r",stdin);
freopen("1222.out","w",stdout);
ll a,b;
Get_Prime(maxn-1);
cin>>a>>b;
cout<<f(b)-f(a-1)<<endl;
return 0;
}