[CSP-S模拟测试]:太阳神(莫比乌斯反演)

Posted wzc521

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CSP-S模拟测试]:太阳神(莫比乌斯反演)相关的知识,希望对你有一定的参考价值。

题目描述

太阳神拉很喜欢最小公倍数,有一天他想到了一个关于最小公倍数的题目。
求满足如下条件的数对$(a,b)$对数:$a,b$均为正整数且$a,b\leqslant n$而$lcm(a,b)>n$。其中的$lcm$当然表示最小公倍数。答案对$1,000,000,007$取模


输入格式

第一行一个正整数$n$。


输出格式

一行一个整数表示答案,对$1,000,000,007$取模。


样例

样例输入:

3

样例输出:

2


数据范围与提示

对于$20\%$的数据$n\leqslant 2,000$;
对于$40\%$的数据$n\leqslant 10,000,000$;
对于$60\%$的数据$n\leqslant 100,000,000$;
对于$80\%$的数据$n\leqslant 1,000,000,000$;
对于$100\%$的数据$n\leqslant 10,000,000,000$。


题解

一般遇到这种题,我们都是先将其化繁,再化简。

就是我们现有一个简,但是时间复杂度高的算法;然后将其化为一个繁,时间复杂度依然高的算法;再将这个算法化成一个既简单时间复杂度又低的算法。

那么我们先将其化繁,哦,不,先化简。

发现直接求$lcm(a,b)>n$很不好求,不妨求其补集,也就是$lca(a,b)<=n$。

开始化繁……

我们知道,$lcm(a,b)=\dfraca\times bgcd(a,b)$,所以式子可以转化为:

$\sum \limits_i=1^n\sum \limits_j=1^n\dfraci\times jgcd(i,j)\leqslant n$

将$gcd(i,j)$乘过去:

$=\sum \limits_i=1^n\sum \limits_j=1^ni\times j\leqslant gcd(i,j)\times n$

发现,我们可以枚举$gcd$,也就是:

$=\sum \limits_g=1^n\sum \limits_i=1^\left \lfloor \dfracng\right \rfloor\sum \limits_j=1^\left \lfloor \dfracng\right \rfloori\times j\times g^2\leqslant g\times n\times [gcd(i,j)==1]$

约去一个$g$:

$=\sum \limits_g=1^n\sum \limits_i=1^\left \lfloor \dfracng\right \rfloor\sum \limits_j=1^\left \lfloor \dfracng\right \rfloori\times j\times g\leqslant n\times [gcd(i,j)==1]$

遇到长这样的$gcd$我们一般考虑莫比乌斯反演。

那么我们又将其化成了:

$\sum\limits_g=1^n\sum\limits_d=1^\left\lfloor\dfracng\right\rfloor\mu (d)\sum\limits_i=1^\left\lfloor\dfracndg\right\rfloor\sum\limits_j=1^\left\lfloor\dfracndg\right\rfloori\times j\times g\times d^2\leqslant n$

因为我们再枚举$\left\lfloor\dfracndg\right\rfloor$以上是没有用的,所以我们可以将其变成:

$\sum \limits_d=1^\sqrtn\mu(d)\sum \limits_g=1^n\sum \limits_i=1^n\sum \limits_j=1^n i\times j\times g\leqslant \dfracnd^2$

那么,我们可以设$i<j<g$,但是需要注意得数需要乘$6$;再设$i,j,g$中有两个相等,那么得数要乘$3$就好啦。

简略证明一下时间复杂度(不知道对不对):

我们在调用函数的时候最外层循环是$i\times i\times i\leqslant n$,内层循环是$i\times j\times j\leqslant n$,在平面直角坐标系上积分可以得到函数的时间复杂度是$\Theta(\fracni^2^\frac23)$,在考虑外面的$\Theta(n^\frac12)$即可得到总的时间复杂度是$\Theta(n^\frac23)$。

时间复杂度:$\Theta(n^\frac23)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
long long n;
int pri[100001],mu[100001],cnt;
bool v[100001];
long long ans;
void pre_work()

    mu[1]=1;
    for(long long i=2;i<=100000;i++)
    
        if(!v[i])mu[pri[++cnt]=i]=-1;
        for(int j=1;j<=cnt&&i*pri[j]<=100000;j++)
        
            v[i*pri[j]]=1;
            if(i%pri[j])mu[i*pri[j]]=-mu[i];
            elsemu[i*pri[j]]=0;break;
        
    

long long get(long long x)

	long long res=0;
	for(long long i=1;i*i*i<=x;i++)
	
		if(i*i*i<=x)res++;
		for(long long j=i+1;i*j*j<x;j++)
			res=(res+6*(x/i/j-j)%mod)%mod;
	
	for(long long i=1;i*i<=x;i++)
		res=(res+3*(x/i/i-(x/i/i>=i))%mod)%mod;
	return res;

int main()

	pre_work();
	scanf("%lld",&n);
	for(long long i=1;i*i<=n;i++)
		if(mu[i])ans=(ans+mu[i]*get(n/i/i)%mod)%mod;
	n%=mod;
	printf("%lld",(n*n-ans+mod)%mod);
	return 0;


rp++

以上是关于[CSP-S模拟测试]:太阳神(莫比乌斯反演)的主要内容,如果未能解决你的问题,请参考以下文章

CSP-S 模拟 轻飘飘的时间 (莫比乌斯反演)(杜教筛)(Lucas)

机房测试3:太阳神 ra (莫比乌斯反演)

莫比乌斯反演的莫比乌斯反演的性质

莫比乌斯反演

莫比乌斯反演

莫比乌斯反演总结