LOJ6181 某个套路求和题

某个套路求和题

从前有个 alpha1022,他在看某本奇妙的书的时候想到了这样一个函数:

[f(n) = prod_{d|n} mu(d) ]

然后就有了这样一个问题:

[sum_{i=1}^n f(i) mod 998244353 ]

然后他就把这个问题扔给了你。

对于 (100\%) 的数据,(n le 10^{10})

题解

http://jklover.hs-blog.cf/2020/04/19/Loj-6181-某个套路求和题/

考虑化简(f(n)=prod_{d|n} mu(d))

(n)有平方因子时,(f(n) = 0),否则我们考虑有几个(mu(d)=-1),就可以算出(mu(n))

(n)(omega(n))种不同的质因子,由于(n)没有平方因子,所以各个质因子的次数都是(1)

(d)(n)的约数可以看做从(omega(n))个质因子中选出一些乘起来组成的,而(mu(d)=-1)等价于选了奇数个。

那么显然有(2^{omega(n)-1})种选法,只有当(n)为质数时有奇数个(mu(d)=-1),其他情况都有偶数个。

于是可以得出

[ ext{ans}=sum_{i=1}^nmu^2(i) -sum_{i=1}^n 2 imes [iin P] ]

后者是(1)(n)中质数个数的(2)倍,可以用Min_25筛求出.

考虑如何求(sum mu^2(i)),记(p(n)=max_{d^2|n} lbrace d brace)表示(n)的最大平方因子,则

[sum_{i=1}^n mu^2(i) \ =sum_{i=1}^n [p(i)=1] \ =sum_{d=1}^n mu(d) sum_{d|p(i)}1 \ =sum_{d=1}^nmu(d) sum_{d^2|i} 1\ =sum_{d=1}^n mu(d) lfloor frac n {d^2} floor ]

于是筛出(sqrt n)以内的(mu),就可以在(O(sqrt n))内计算出(sum mu^2(i))了。

CO int N=2e5+10,mod=998244353;
int prime[N],num,mu[N];
int pos[N],idx,ref1[N],ref2[N],H[N];

signed main(){
	int n=read<int>(),m=ceil(sqrt(n));
	mu[1]=1;
	for(int i=2;i<=m;++i){
		if(!prime[i]) prime[++num]=i,mu[i]=-1;
		for(int j=1;j<=num and i*prime[j]<=m;++j){
			prime[i*prime[j]]=1;
			if(i%prime[j]==0) break;
			mu[i*prime[j]]=-mu[i];
		}
	}
	for(int l=1,r;l<=n;l=r+1){
		r=n/(n/l);
		pos[++idx]=n/l;
		if(n/l<=m) ref1[n/l]=idx;
		else ref2[n/(n/l)]=idx;
	}
	for(int i=1;i<=idx;++i) H[i]=pos[i]-1;
	for(int j=1;j<=num;++j)
		for(int i=1;i<=idx and prime[j]*prime[j]<=pos[i];++i){
			int k=pos[i]/prime[j];
			if(k<=m) k=ref1[k];
			else k=ref2[n/k];
			H[i]-=H[k]-(j-1);
		}
	int ans=0;
	for(int i=1;i*i<=n;++i) ans+=mu[i]*(n/(i*i));
	ans-=2*H[1];
	printf("%lld
",(ans%mod+mod)%mod);
	return 0;
}
原文地址:https://www.cnblogs.com/autoint/p/12775587.html