Luogu P2257 YY的GCD

数论太难了吧...

Here


给定 \(n\),\(m\),\(T\),\(T\) 为数据组数,求:

\[\sum\limits_{p\in \operatorname{prime}}\sum\limits_{i=1}^n\sum\limits_{j=1}^m[\gcd(i,j)=p] \]

\(n,m\le 1\times 10^7\),\(T=10^4\)

首先推推式子吧:

\[\sum\limits_{p\in \operatorname{prime}}\sum\limits_{i=1}^n\sum\limits_{j=1}^m[\gcd(i,j)=p] \]

\[\sum\limits_{p\in \operatorname{prime}}\sum\limits_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{p}\rfloor}[\gcd(i,j)=1] \]

因为

\[\sum\limits_{d\mid n}\mu(d)=[n=1] \]

所以有

\[\sum\limits_{d\mid \gcd(i,j)}\mu(d)=[\gcd(i,j)=1] \]

替换,得到

\[\sum\limits_{p\in \operatorname{prime}}\sum\limits_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{p}\rfloor}\sum\limits_{d\mid \gcd(i,j)}\mu(d) \]

枚举 \(d\)

\[\sum\limits_{p\in \operatorname{prime}}\sum\limits_{d=1}^{\min(n,m)}\mu(d)\lfloor\frac{n}{pd}\rfloor\lfloor\frac{m}{pd}\rfloor \]

设 \(T=pd\),枚举 \(T\)

\[\sum\limits_{T=1}^{\min(n,m)}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum\limits_{p\mid T}\mu(\frac{T}{p})[p\in \operatorname{prime}] \]

这样前面就是一个整除分块,复杂度是 \(\operatorname{O}(T\sqrt n)\):

while(T--){
	n=read(),m=read();
	if(n>m) swap(n,m);
	int l=1,r;
	ll ans=0;
	for(l=1;l<=n;l=r+1){
		r=min(n/(n/l),m/(m/l));
		ans+=(ll)(n/l)*(ll)(m/l)*(ll)(F[r]-F[l-1]);
	}
	printf("%lld\n",ans);
}

设:

\[f(p)=[p\in \operatorname{prime}] \]

\[\begin{aligned} F(T)&=\sum\limits_{p\mid T}\mu(\frac{T}{p})[p\in \operatorname{prime}]\\&=\sum\limits_{p\mid T}\mu(\frac{T}{p})f(p) \end{aligned} \]

于是我们要求的就是 \(F\) ,怎么求呢?

solution 1

这不就是 \(F=\mu *f\) 吗,直接大力卷积!

(\(\mu\) 线性筛就好了):

FOR(i,1,N){
	FOR(j,1,N){
		if(i*j>N) break;
		F[i*j]+=mu[i]*f[j];
	}
}

每一个 \(i\) 只会被算 \(\lfloor\frac{n}{i}\rfloor\) 次,\(\sum\frac{n}{i}=n\sum\frac{1}{i}\),是个调和级数,差不多 \(\operatorname{O}(n\ln n)\),能过,但是要吸氧。

另:

根据 \(\mu\) 函数的定义,我们可以得出以下的代码:

FOR(i,1,N)
	for(int j=i*2;j<=N;j+=i)
		f[j]-=f[i];

这样新的 \(f\) 就是我们要求的 \(F\) 了,但是我不会证,一样是 \(\operatorname{O}(n\ln n)\)。

这种方法不用线性筛,会比上面的稍快一点

solution 2

\[F(T)=\sum\limits_{p\mid T}\mu(\frac{T}{p})f(p) \]

对于这一坨东西,我们其实可以用类似埃氏筛的办法解决,这样要快许多。

具体地,可以观察到只有 \(p\) 为质数时才会累加,那么就枚举质数,对它的倍数进行累加即可:

FOR(i,1,cnt)
	for(int j=1;j*p[i]<=N;j++)
		f[j*p[i]]+=mu[j];

复杂度约为 \(\operatorname{O}(n\ln\ln n)\),不用吸氧了。

solution 3

抛开以上所有式子,重新来看这个题:

\[\sum\limits_{i=1}^n\sum\limits_{j=1}^m[\gcd(i,j)\in \operatorname{prime}] \]

如果我们能够构造一个

\[\sum\limits_{d\mid n}F(d)=[n\in \operatorname{prime}] \]

那么就

\[\sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{d\mid \gcd(i,j)}F(d) \]

\[\sum\limits_{d=1}^{\min(n,m)}F(d)\lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor \]

所以重点是如何构造 \(F\)。

设

\[f(n)=[n\in \operatorname{prime}] \]

那么我们想构造的 \(F\) 就有

\[f(n)=\sum\limits_{d\mid n}F(d) \]

所以

\[F(n)=\sum\limits_{d\mid n}\mu(d)f(\frac{n}{d}) \]

\[F=\mu*f \]

回到 solution 1,就做完了。所以只是换了个角度思考,实质还是没有区别啊!


至此,解法已经有好多了,可以通过此题。但是

太慢了!我们需要线性求 F!

所以:

solution 4

还是回到那个式子:

\[f(p)=[p\in \operatorname{prime}] \]

\[F(T)=\sum\limits_{p\mid T}\mu(\frac{T}{p})f(p) \]

我们不妨改写成前一步的样子:

\[F(T)=\sum\limits_{p\mid T}\mu(\frac{T}{p})[p\in \operatorname{prime}] \]

好像可以线性筛出来啊!

先看看这个 \(F(T)\) 是不是积性的。

\(F=\mu *f\),所以 \(F(1)\dots\),没有质数能整除 \(1\) 啊,那 \(F(1)=0\)?那就不是积性函数呗。我一直以为只有积性函数可以用欧拉筛,这下看起来不是积性函数也能筛,满足条件就行了呗。

  • 我们假设 \(T=i\times k\),\(k\) 是 \(T\) 的最小质因子。(以下自动忽略非素数的 \(p\))

  • ① 如果 \(T\in \operatorname{prime}\),那么 \(F(T)=\mu(1)=1\)

  • ② \(i\bmod k=0\),也就是说 \(T\) 存在多个最小质因子

    • 若 \(\mu(i)\neq0\),则当且仅当 \(p=k\) 时,\(\mu(\frac{T}{p})=\mu(i)\neq0\),其余情况 \(\mu(\frac{T}{p})\) 因为多个质因子 \(k\) 的存在都等于 \(0\),所以 \(F(T)=\mu(i)\)
    • 若 \(\mu(i)=0\),则 \(p\neq k\) 时,\(\mu(\frac{T}{p})=0\);\(p=k\) 时,\(\mu(\frac{T}{p})=\mu(i)=0\)。所以 \(F(T)=\mu(i)\)

    综上 \(i\bmod k=0\) 时,\(F(T)=\mu(i)\)

  • ③ \(i\bmod k\ne0\)

我们在做线性筛的时候,是从 \(i\) 推到 \(T\) 的,观察:

\[F(i)=\sum\limits_{p\mid i}\mu(\frac{i}{p})[p\in \operatorname{prime}] \]

\[F(T)=\sum\limits_{p\mid T}\mu(\frac{i\times k}{p})[p\in \operatorname{prime}](T=i\times k) \]

\[\mu(\frac{i\times k}{p})=-\mu(\frac{i}{p}) \]

那也就是说,\(T\) 比 \(i\) 多了一个质因子 \(k\),则 \(F(T)\) 比 \(F(i)\) 多了一个 \(\mu(\frac{i\times k}{p(p=k)})=\mu(i)\)

观察第三个式子,所有 \(\mu\) 又都要取反,最终得到了:

\[F(T)=-F(i)+\mu(i) \]


由此我们写出线性筛总式(姑且这么叫吧)就是:

\(F(T)=\begin{cases}F(T)=1&T\in \operatorname{prime}\\F(T)=\mu(i)&i\bmod k=0\\F(T)=-F(i)+\mu(i)&i\bmod k\neq 0\end{cases}\)

所以求 \(F\) 的复杂度是 \(\operatorname{O}(n)\) 的。

愉快的代码时间~


void init(){
	bitset<N>isp;
	isp.set();
	isp[1]=0;
	mu[1]=1;
	FOR(i,2,N){
		if(isp[i]) p[++cnt]=i,mu[i]=-1,F[i]=1;
		for(int j=1;i*p[j]<=N&&j<=cnt;j++){
			isp[i*p[j]]=0;
			if(i%p[j]==0){
				mu[i*p[j]]=0;
				F[i*p[j]]=mu[i];
				break;
			}
			F[i*p[j]]=-F[i]+mu[i];
			mu[i*p[j]]=-mu[i];
		}
	}
	FOR(i,1,N) F[i]+=F[i-1];
}

至此,本题得到了完美解决 大概

(以上内容整理自题解)

\[\color{Pink}\text{完结撒花} \]

posted @ 2024-01-23 17:00  LHLeisus  阅读(44)  评论(0)    收藏  举报