51nod1222 最小公倍數計數 【莫比烏斯反演】
阿新 • • 發佈:2018-12-26
題目描述
求
題目分析
實質上就是求
的數量,最後加上n,再除以2
看到這種條件裡面帶不等式的,求和符號能省去範圍的就省掉,不然會很冗雜
列舉gcd:
反演,去掉[(i,j)==1]:
那麼現在就是求
假設
,那麼只需要列舉不超過
的
,再列舉不超過
的
,統計c的個數,在配上對應的容斥係數,考慮一下兩個數,三個數相等的情況即可。
求
的時間複雜度為
,
- PS:
列舉 ,原式
問題等同於Counting Divisors
#include<cstdio>
#define LL long long
const int N = 10000005;
int p[N/10],mu[N+5];
bool v[N+5];
void Prime()
{
mu[1]=1;int cnt=0;
for(int i=2;i<=N;i++)
{
if(!v[i]) p[++cnt]=i,mu[i]=-1;
for(int j=1,k;j<=cnt&&p[j]*i<=N;j++)
{
v[k=p[j]*i]=1;
if(i%p[j]==0) {mu[k]=0;break;}
mu[k]=-mu[i];
}
}
}
LL solve(LL n)
{
LL ans=0;
for(LL k=1;k*k<=n;k++) if(mu[k])
{
LL m = n/(k*k), ret=0;
for(LL i=1;i*i*i<=m;i++)
{
for(LL j=i+1;i*j*j<=m;j++) ret+=(m/(i*j)-j)*6+3;
ret+=(m/(i*i)-i)*3+1;
}
ans+=mu[k]*ret;
}
return (ans+n)/2;
}
int main()
{
Prime();
LL a,b;
scanf("%lld%lld",&a,&b);