[CODECHEF]LCM

Posted jefflyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CODECHEF]LCM相关的知识,希望对你有一定的参考价值。

题意:询问满足$1leq xleq n,1leq yleq m$且$x,y$均无平方因子的有序对$(x,y)$的$[x,y]$之和,多组数据

以下假设$nleq m$,设$S(n)=frac{n(n+1)}2$,$r(n)$表示$n$的最大无平方因子

$egin{align*}sumlimits_{i=1}^nsumlimits_{j=1}^mmu^2left((i,j) ight)[i,j]&=sumlimits_{d=1}^ndmu^2(d)sumlimits_{i=1}^{leftlfloorfrac nd ight floor}sumlimits_{j=1}^{leftlfloorfrac md ight floor}[i,j][(i,j)=1]\&=sumlimits_{d=1}^ndmu^2(d)sumlimits_{e=1}^{leftlfloorfrac nd ight floor}emu(e)sumlimits_{i=1}^{leftlfloorfrac n{de} ight floor}sumlimits_{j=1}^{leftlfloorfrac m{de} ight floor}[i,j]\&=sumlimits_{T=1}^nTsumlimits_{d|T}mu^2(d)muleft(frac Td ight)sumlimits_{i=1}^{leftlfloorfrac nT ight floor}sumlimits_{j=1}^{leftlfloorfrac mT ight floor}[i,j]end{align*}$

暂停一下,先化一下其中的一部分式子

1.$G(n)=sumlimits_{d|n}mu^2(d)muleft(frac nd ight)$

设$n=a^2b$,其中$mu(b) e0$,那么仅当$d=ac$且$(a,c)=1$时$mu^2(d)muleft(frac nd ight) e0$(若$a mid d$则$frac nd$含来自$a$的平方因子,若$(a,c) e1$则$d$含平方因子),此时$G(n)=sumlimits_{c|b}muleft(frac{a^2b}{ac} ight)=mu(a)sumlimits_{c|b}muleft(frac bc ight)=mu(a)[b=1]$,这说明当$n$为完全平方数时,$G(n)=muleft(sqrt n ight)$,否则$G(n)=0$

2.$F(n,m)=sumlimits_{i=1}^nsumlimits_{j=1}^m[i,j]$

直接把jzptab的式子搬过来,$F(n,m)=sumlimits_{T=1}^nTSleft(leftlfloorfrac nT ight floor ight)Sleft(leftlfloorfrac mT ight floor ight)sumlimits_{e|T}emu(e)$

这里我们每次求答案都要求很多次$F$,所以还要继续推下去

$Q(n)=sumlimits_{e|n}emu(e)$

首先显然$Q(n)=Q(r(n))$,因为$n$的平方因子对答案没有贡献,接下来考虑$n=r(n)$的情况,设$n=prodlimits_{i=1}^kp_i$

当$n$为质数时$Q(n)=1-n$,因为$Q$是个积性函数,所以$Q(n)=prodlimits_{i=1}^k(1-p_i)=(-1)^kvarphi(n)=mu(n)varphi(n)$,即是说对于一般的$n$有$Q(n)=mu(r(n))varphi(r(n))$

把以上两个结果代入到开始时的式子中,得到$sumlimits_{p=1}^{leftlfloorsqrt n ight floor}p^2mu(p)sumlimits_{q=1}^{leftlfloorfrac n{p^2} ight floor}qQ(q)Sleft(leftlfloorfrac n{p^2q} ight floor ight)Sleft(leftlfloorfrac m{p^2q} ight floor ight)$

枚举$T=p^2q$,得到$sumlimits_{T=1}^nTSleft(leftlfloorfrac nT ight floor ight)Sleft(leftlfloorfrac mT ight floor ight)sumlimits_{p^2|T}mu(p)Qleft(frac T{p^2} ight)$

我们要预处理$D(n)=sumlimits_{p^2|n}mu(p)Qleft(frac n{p^2} ight)$,这个直接枚举$p$去更新$p^2$的倍数即可,时间复杂度为$Oleft(nsumlimits_{i=1}^{leftlfloorsqrt n ight floor}frac1{i^2} ight)=O(n)$

总时间复杂度$Oleft(n+Tsqrt n ight)$,这题还是挺棒的==

一个小小的trick:我们可以算出答案的$4$倍$mod2^{32}$的值,最后$div4$即可,这样在求$S(n)$的时候不用$div2$而且可以全程unsigned

#include<stdio.h>
typedef unsigned uint;
const int T=4000010;
int min(int a,int b){return a<b?a:b;}
void swap(int&a,int&b){a^=b^=a^=b;}
int pr[T+10],r[T+10],mu[T+10],phi[T+10];
bool np[T+10];
uint D[T+10];
void sieve(){
	int i,j,M;
	M=0;
	r[1]=1;
	mu[1]=1;
	phi[1]=1;
	for(i=2;i<=T;i++){
		if(!np[i]){
			pr[++M]=i;
			r[i]=i;
			mu[i]=-1;
			phi[i]=i-1;
		}
		for(j=1;j<=M&&i*pr[j]<=T;j++){
			np[i*pr[j]]=1;
			if(i%pr[j]==0){
				r[i*pr[j]]=r[i];
				phi[i*pr[j]]=phi[i]*pr[j];
				break;
			}
			r[i*pr[j]]=r[i]*pr[j];
			mu[i*pr[j]]=-mu[i];
			phi[i*pr[j]]=phi[i]*(pr[j]-1);
		}
	}
	for(i=1;i*i<=T;i++){
		if(mu[i]){
			for(j=i*i;j<=T;j+=i*i)D[j]+=mu[i]*mu[r[j/(i*i)]]*phi[r[j/(i*i)]];
		}
	}
	for(i=1;i<=T;i++)D[i]=D[i]*i;
	for(i=1;i<=T;i++)D[i]+=D[i-1];
}
uint S(uint n){return n*(n+1);}
uint solve(int n,int m){
	uint s;
	int i,nex;
	for(i=1;i<=n;i=nex+1){
		nex=min(n/(n/i),m/(m/i));
		s+=(D[nex]-D[i-1])*S(n/i)*S(m/i);
	}
	return s;
}
int main(){
	sieve();
	int T,n,m;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		if(n>m)swap(n,m);
		printf("%u
",solve(n,m)>>2);
	}
}

以上是关于[CODECHEF]LCM的主要内容,如果未能解决你的问题,请参考以下文章

Codechef 虫洞:我的逻辑有啥问题?

codechef问题COVIDLQ错误的应答错误

CodeChef GRAPHCNT

BZOJ4260: Codechef REBXOR

Codechef October Challenge 2018 游记

CodeChef Chef and Digit Jumps 题解