DZY Loves Math

III.DZY Loves Math

题意:求

\(\sum\limits_{i=1}^n\sum\limits_{j=1}^mf(\gcd(i,j))\),其中\(f(x)\)表示\(x\)的所有质因数中次数最高的一个的次数。

近乎套路的一堆操作后,我们得到了

\(\sum\limits_{i=1}^{\min(n,m)}\left\lfloor\dfrac{n}{i}\right\rfloor\left\lfloor\dfrac{m}{i}\right\rfloor(f*\mu)(i)\)

但是,稍微想想就发现,\(f\)函数并不是积性函数。例如,\(f(5)=1,f(6)=1,\gcd(5,6)=1,f(5*6)=f(30)=1\)

那怎么办呢?

考虑\((f*\mu)(x)=\sum\limits_{d|x}\mu(d)f(\dfrac{x}{d})\)

我们设\(x=\prod_{i=1}^k(P_i)^{a_i}\)

显然,只有当\(d=\prod_{i=1}^k(P_i)^{b_i},b_i\in\{0,1\}\)时,才有\(\mu(d)\neq 0\)

我们设某个具有\(\min(a_i)\)\(P_i\)\(p\)

再设一个\(d|x\)\(\gcd(d,p)=1\)\(d\)

则,\(\mu(d)=-\mu(dp),f(\dfrac{x}{d})=f(\dfrac{x}{dp})\)

\(\mu(d)f(\dfrac{x}{d})+\mu(dp)f(\dfrac{x}{dp})=0\)

因此,大部分情况下,\((f*\mu)(x)=0\)

唯一的特例就是所有的\(a_i\)全部相等时。这时,就算是\(\min(a_i)\)也会对\(f\)有影响。

当然,除了\(d=1\)\(d=\prod_{i=1}^k(P_i)\)两个值以外,其他的\(\mu(d)f(\dfrac{x}{d})\)还是会互相抵消掉。

\(d=1\)时,\(\mu(d)f(\dfrac{x}{d})=a_i\);当\(d=\prod_{i=1}^k(P_i)\)时,\(\mu(d)f(\dfrac{x}{d})=(a_i-1)*\mu(d)\)

这两个求和的话,我们最终得到了\(-\mu(d)\)

我们设\(f*\mu=g\)。然后就只要枚举每个\(\mu(x)\neq 0\)\(x\),将它的所有次方的\(g\)设为\(-\mu(x)\)即可。这个复杂度为\(O(n)\),因为每一个\(g(x)\)只会被访问一次。

虽然这是莫反题,但本题最大的难点是线性时间内求出\(f*\mu\)的值。数学素养是很重要的。(就像我,根本求不出来\(f*\mu\)到底是个什么东西

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e7;
int n,m,pri[N+5],mu[N+5],g[N+5],T,res;
void init(){
	mu[1]=1;
	for(int i=2;i<=N;i++){
		if(!pri[i])pri[++pri[0]]=i,mu[i]=-1;
		for(int j=1;j<=pri[0]&&i*pri[j]<=N;j++){
			pri[i*pri[j]]=true;
			if(!(i%pri[j]))break;
			mu[i*pri[j]]=-mu[i];
		}
	}
	for(int i=2;i<=N;i++)if(mu[i])for(int j=i;j<=N;j*=i)g[j]=-mu[i];
	for(int i=1;i<=N;i++)g[i]+=g[i-1];
}
signed main(){
	scanf("%lld",&T),init();
	while(T--){
		scanf("%lld%lld",&n,&m),res=0;
		for(int l=1,r;l<=min(n,m);l=r+1)r=min(n/(n/l),m/(m/l)),res+=(g[r]-g[l-1])*(n/l)*(m/l);
		printf("%lld\n",res);
	}
	return 0;
}

posted @ 2021-04-05 21:44  Troverld  阅读(39)  评论(0编辑  收藏  举报