BZOJ 2154: Crash的数字表格 莫比乌斯反演

数学挑战:求最小公倍数表格的和
本文探讨了一种数学问题,即求解一个由最小公倍数构成的N*M表格中所有数的和,并提供了一种高效的算法解决方案。通过数学公式推导,将问题转化为更易于计算的形式,利用预处理技术和优化技巧,实现了解决大规模问题的目标。

Description

今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple)。对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数。例如,LCM(6, 8) = 24。回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张N*M的表格。每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j)。一个4*5的表格如下: 1 2 3 4 5 2 2 6 4 10 3 6 3 12 15 4 4 12 4 20 看着这个表格,Crash想到了很多可以思考的问题。不过他最想解决的问题却是一个十分简单的问题:这个表格中所有数的和是多少。当N和M很大时,Crash就束手无策了,因此他找到了聪明的你用程序帮他解决这个问题。由于最终结果可能会很大,Crash只想知道表格里所有数的和mod 20101009的值。

Input

输入的第一行包含两个正整数,分别表示N和M。

Output

输出一个正整数,表示表格中所有数的和mod 20101009的值。 

题解:

求 $\sum_{i=1}^{n}\sum_{j=1}^{m}lcm(i,j)$

首先,定义 $n\leqslant m$

开始推公式

$\sum_{i=1}^{n}\sum_{j=1}^{m}lcm(i,j)$

$=\sum_{i=1}^{n}\sum_{j=1}^{m}\frac{i\times j}{gcd(i,j)}$

$=\sum_{d=1}^{n}d\times \sum_{i=1}^{\left \lfloor \frac{n}{d} \right\rfloor}\sum_{j=1}^{\left \lfloor \frac{m}{d} \right\rfloor}i\times j[gcd(i,j)==1]$

定义 $calc(n,m)=\sum_{i=1}^{n}\sum_{j=1}^{m}i\times j[gcd(i,j)==1]$

$calc(n,m)=\sum_{i=1}^{n}\sum_{j=1}^{m}i\times j\sum_{d|i,d|j}\mu(d)$

$=\sum_{d=1}^{n}\mu(d)\sum_{d|i}i\sum_{d|j}j$

$=\sum_{d=1}^{n}\mu(d)\sum_{i=1}^{\frac{n}{d}}id\sum_{j=1}^{\frac{m}{d}}jd$

$=\sum_{d=1}^{n}\mu(d)d^{2}\sum_{i=1}^{\frac{n}{d}}d\sum_{j=1}^{\frac{m}{d}}j$

发现后面那个$\sum_{i=1}^{\frac{n}{d}}d\sum_{j=1}^{\frac{m}{d}}j$可以 $O(1)$ 求出.

$=\frac{(1+\frac{n}{d})\frac{n}{d}}{2}\times\frac{(1+\frac{m}{d})\frac{m}{d}}{2}$

我们把它定义为 $Sum(\frac{n}{d},\frac{m}{d})$

可知 $calc(n,m)=\sum_{d=1}^{n}\mu(d)d^{2}Sum(\frac{n}{d},\frac{m}{d})$

可以预处理 $\mu(d)d^2$,所以这一部分的时间复杂度是 $n^{\frac{1}{2}}$ 的.

回到原式$=\sum_{d=1}^{n}d\times calc(\frac{n}{d},\frac{m}{d})$

总时间复杂度是 $O(n)$ 的. 
#include<bits/stdc++.h>
#define maxn 10010006
#define ll long long  
using namespace std;
const long long mod = 1ll*20101009;  
void setIO(string s)
{
	string in=s+".in"; 
	freopen(in.c_str(),"r",stdin); 
}
int cnt; 
int prime[maxn], vis[maxn], mu[maxn]; 
ll sumv[maxn]; 
inline void init(int hh) 
{
	int i,j;
	mu[1]=sumv[1]=1; 
	for(i=2;i<hh;++i)
	{
		if(!vis[i]) prime[++cnt]=i, mu[i]=-1; 
		for(j=1;j<=cnt&&1ll*prime[j]*i<hh;++j) 
		{
			vis[prime[j]*i]=1; 
			if(i%prime[j]!=0) mu[i*prime[j]]=-mu[i]; 
			else 
			{
				mu[i*prime[j]]=0; 
				break; 
			}
		}
		sumv[i]=(sumv[i-1]+1ll*i*i%mod*(mu[i]+mod))%mod;    
		//  sumv2[i]=(i+sumv2[i-1])%mod; 
	} 
}
inline ll getarr(ll n,ll m)
{
	ll tmp=(1ll*n*(n+1)/2%mod) * (1ll*m*(m+1)/2%mod)%mod;  
    return tmp; 
}
inline ll calc(ll n,ll m)
{
	ll i,j; 
	ll ans=0; 
	for(i=1;i<=n;i=j+1)
	{
		j=min(n/(n/i), m/(m/i));  
		ans=(ans+1ll*(sumv[j]-sumv[i-1]+mod)*getarr(n/i,m/i)%mod)%mod;  
	}
	return ans; 
}
int main()
{
// 	setIO("input");  
	ll n,m,i,j; 
	ll ans=0; 
	scanf("%lld%lld",&n,&m); 
	if(n>m)swap(n,m);        
	init(m + 1); 
	for(i=1;i<=n;i=j+1)
	{
		j=min(n/(n/i), m/(m/i));  
		ans=(ans+1ll*((j-i+1)*(i+j)/2)%mod*calc(n/i,m/i)%mod)%mod;   
		ans=(ans+mod)%mod;  
	}  
	printf("%lld\n",ans); 
	return 0; 
}

  

转载于:https://www.cnblogs.com/guangheli/p/11084707.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值