[CF235E]Number Challenge

$\newcommand{fl}[1]{\left\lfloor#1\right\rfloor}$题意:求$\sum\limits_{i=1}^a\sum\limits_{j=1}^b\sum\limits_{k=1}^c\sigma_0(ijk)$

做这题要用到一个结论:$\sum\limits_{i=1}^a\sum\limits_{j=1}^b\sum\limits_{k=1}^c\sigma_0(ijk)=\sum\limits_{\substack{(i,j)=(j,k)=(k,i)=1\\i\leq a,j\leq b,k\leq c}}\fl{\frac ai}\fl{\frac bj}\fl{\frac ck}$,证明如下

令$f(a,b,c)=\sum\limits_{i=1}^a\sum\limits_{j=1}^b\sum\limits_{k=1}^c\sigma_0(ijk),g(a,b,c)=\sum\limits_{\substack{(i,j)=(j,k)=(k,i)=1\\i\leq a,j\leq b,k\leq c}}\fl{\frac ai}\fl{\frac bj}\fl{\frac ck}$

对$f$容斥

$f(a,b,c)-f(a-1,b,c)-f(a,b-1,c)-f(a,b,c-1)+f(a-1,b-1,c)+f(a-1,b,c-1)+f(a,b-1,c-1)-f(a-1,b-1,c-1)=\sigma_0(abc)$

对$g$写出形式相同的式子

$g(a,b,c)-g(a-1,b,c)-g(a,b-1,c)-g(a,b,c-1)+g(a-1,b-1,c)+g(a-1,b,c-1)+g(a,b-1,c-1)-g(a-1,b-1,c-1)\\=\sum\limits_{\substack{(i,j)=(j,k)=(k,i)=1\\i\leq a,j\leq b,k\leq c}}\left(\fl{\frac ai}-\fl{\frac{a-1}i}\right)\left(\fl{\frac bj}-\fl{\frac{b-1}j}\right)\left(\fl{\frac ck}-\fl{\frac{c-1}k}\right)$

观察$g$的这条式子,只有$i|a,j|b,k|c$时,右边的三个括号才会有$1$的贡献,所以它统计的是满足$(i,j)=(j,k)=(k,i)=1$且$i|a,j|b,k|c$的$(i,j,k)$组数

对一个质数$p$,设$x$为满足$p^x|a$的最大$x$,类似地定义$y,z$

仅由$p$构成的$abc$的约数有$x+y+z+1$个($1$也被算入)

仅由$p$构成的$(i,j,k)$有$x+y+z+1$组($(1,1,1),(p^{1\cdots x},1,1),(1,p^{1\cdots y},1),(1,1,p^{1\cdots z})$)

又因为这俩都是积性函数,所以我们证明了$\sigma_0(abc)=\sum\limits_{\substack{(i,j)=(j,k)=(k,i)=1\\i|a,j|b,k|c}}$

这样一来,$f$和$g$的递推式就一模一样了,又因为$f(1,1,1)=g(1,1,1)=1$,所以$f(a,b,c)=g(a,b,c)$,得证

我们再回来推这题的公式

$\begin{align*}\sum\limits_{i=1}^a\sum\limits_{j=1}^b\sum\limits_{k=1}^c\sigma_0(ijk)&=\sum\limits_{\substack{(i,j)=(j,k)=(k,i)=1\\i\leq a,j\leq b,k\leq c}}\fl{\frac ai}\fl{\frac bj}\fl{\frac ck}\\&=\sum\limits_{i=1}^a\sum\limits_{j=1}^b[(i,j)=1]\fl{\frac ai}\fl{\frac bj}\sum\limits_{k=1}^c[(k,ij)=1]\fl{\frac ck}\\&=\sum\limits_{i=1}^a\sum\limits_{j=1}^b[(i,j)=1]\fl{\frac ai}\fl{\frac bj}\sum\limits_{d|ij}\mu(d)\sum\limits_{k=1}^{\fl{\frac cd}}\fl{\frac c{kd}}\end{align*}$

令$f(n)=\sum\limits_{d|n}\mu(d)\sum\limits_{k=1}^{\fl{\frac cd}}\fl{\frac c{kd}}$,我们需要预处理出$f(1\cdots ab)$的值

注意到当$d$确定的时候,第二个sigma的值也确定了,所以我们枚举$d$,计算第二个sigma的值,并更新$d$的倍数的$f(n)$

最后统计答案即可,总时间复杂度$O\left(ab\log_2(ab)\right)$

#include
typedef long long ll;
const int mod=1<<30,T=4000000;
int max(int a,int b){return a>b?a:b;}
int mul(int a,int b){return a*(ll)b%mod;}
void inc(int&a,int b){(a+=b)%=mod;}
int pr[T+10],mu[T+10],M;
bool np[T+10];
void sieve(){
	int i,j,M;
	M=0;
	mu[1]=1;
	for(i=2;i<=T;i++){
		if(!np[i]){
			M++;
			pr[M]=i;
			mu[i]=-1;
		}
		for(j=1;j<=M&&pr[j]*(ll)i<=T;j++){
			np[i*pr[j]]=1;
			if(i%pr[j]==0)break;
			mu[i*pr[j]]=-mu[i];
		}
	}
}
int f[T+10],g[2010][2010];
int main(){
	sieve();
	int a,b,c,i,j,d,ans;
	scanf("%d%d%d",&a,&b,&c);
	for(d=1;d<=a*b;d++){
		if(mu[d]){
			j=0;
			for(i=1;i<=c/d;i++)inc(j,c/(i*d));
			j*=mu[d];
			for(i=d;i<=a*b;i+=d)inc(f[i],j);
		}
	}
	for(i=1;i<=max(a,b);i++){
		for(j=1;j<=i;j++){
			if(i%j==0)
				g[i][j]=j;
			else
				g[i][j]=g[j][i%j];
		}
	}
	for(i=1;i<=max(a,b);i++){
		for(j=i+1;j<=max(a,b);j++)g[i][j]=g[j][i];
	}
	ans=0;
	for(i=1;i<=a;i++){
		for(j=1;j<=b;j++){
			if(g[i][j]==1)inc(ans,mul(mul(a/i,b/j),f[i*j]));
		}
	}
	printf("%d",ans);
}

转载于:https://www.cnblogs.com/jefflyy/p/9207872.html

你可能感兴趣的:([CF235E]Number Challenge)