ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[NOI2010]能量采集

2021-04-05 21:33:20  阅读:236  来源: 互联网

标签:nm min dfrac sum mu 采集 NOI2010 dx 能量


v.[NOI2010]能量采集

真正自己做出来的第一道莫反题祭~~~~

题意:

求\(\sum_{i=1}^n\sum_{j=1}^m(2\gcd(i,j)-1)\)。

开始推式子:

\(\begin{aligned}\sum_{i=1}^n\sum_{j=1}^m(2\gcd(i,j)-1) & =2\sum_{i=1}^n\sum_{j=1}^m\gcd(i,j)-nm\\ & =2\sum_{d=1}^{\min(n,m)}\sum_{i=1}^n\sum_{j=1}^md[\gcd(i,j)=d]-nm\\ & =2\sum_{d=1}^{\min(n,m)}d\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=d]-nm\\ & =2\sum_{d=1}^{\min(n,m)}d\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}[\gcd(i,j)=1]-nm\\ & =2\sum_{d=1}^{\min(n,m)}d\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}\sum_{x|\gcd(i,j)}\mu(x)-nm\\ & =2\sum_{d=1}^{\min(n,m)}d\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}\sum_{x|i,x|j}\mu(x)-nm\\ & =2\sum_{d=1}^{\min(n,m)}d\sum_{x=1}^{\min(n/d,m/d)}\sum_{i=1}^{n/(dx)}\sum_{j=1}^{m/(dx)}\mu(x)-nm\\ & =2\sum_{d=1}^{\min(n,m)}d\sum_{x=1}^{\min(n/d,m/d)}\mu(x)\sum_{i=1}^{n/(dx)}\sum_{j=1}^{m/(dx)}1-nm\\ & =2\sum_{d=1}^{\min(n,m)}d\sum_{x=1}^{\min(n/d,m/d)}\mu(x)\left\lfloor\dfrac{n}{dx}\right\rfloor\left\lfloor\dfrac{m}{dx}\right\rfloor -nm\end{aligned}\)

到这里为止,就已经可以做了。

复杂度为(设\(n\)与\(m\)同级)\(O(\sum_{i=1}^n\sqrt{\dfrac{n}{i}})\approx O(n)\)。

但实际上还有\(O(\sqrt{n})\)的做法(虽然预处理是\(O(n)\)的):

\(2\sum_{d=1}^{\min(n,m)}d\sum_{x=1}^{\min(n/d,m/d)}\mu(x)\left\lfloor\dfrac{n}{dx}\right\rfloor\left\lfloor\dfrac{m}{dx}\right\rfloor -nm\)

设\(T=dx\),则

\(\begin{aligned}\text{原式} & =2\sum_{T=1}^{\min(n,m)}\left\lfloor\dfrac{n}{T}\right\rfloor\left\lfloor\dfrac{m}{T}\right\rfloor\sum_{d|T}d\mu(\dfrac{T}{d})-mn\end{aligned}\)

这东西不还是\(O(n)\)的吗?

我们看一下后面的东西:\(\sum_{d|T}d\mu(\dfrac{T}{d})\),

我们规定一个函数\(id(x)=x\),则这个东西\(=\sum_{d|T}id(d)\mu(\dfrac{T}{d})\)。

这个运算,有一个具体的名字,叫做狄利克雷卷积。它是这样的运算:

\(\boxed{h(n)=(f*g)(n)\Leftrightarrow h(n)=\sum_{d|T}f(d)*g(\dfrac{T}{d})}\)。

这个运算,满足:

\(\boxed{\begin{cases}\text{1.交换律:}f*g=g*f\\\text{2.结合律:}(f*g)*h=f*(g*h)\\\text{3.分配律:}h*(f+g)=h*f+h*g\end{cases}}\)

它的更多性质我们将在接下来一一提到。不过,在这道题中它最大的作用是帮助我们将上面的东西转成狄利克雷卷积的形式,即

\(\begin{aligned}\text{原式} & =2\sum_{T=1}^{\min(n,m)}\left\lfloor\dfrac{n}{T}\right\rfloor\left\lfloor\dfrac{m}{T}\right\rfloor((id*\mu)(T))-mn\end{aligned}\)

好好好,我们搞出了一个新的运算。但是这有什么用吗?

\(\boxed{\text{如果}f\text{和}g\text{都是积性函数,那么}f*g\text{也是积性函数。}}\)

是积性函数就意味着我们可以用欧拉筛去筛它!

而我们已经知道了\(\mu\)函数是积性函数。用脑子稍微想想也知道,\(id\)函数肯定是积性函数。

这意味着,\(id*\mu\)也是一个积性函数,可以用欧拉筛。

而这个东西前一半的东西可以整除分块

那么我们就丧心病狂地把这个东西优化到了\(O(\sqrt{n})\)。

尽管预处理还是\(O(n)\)的,但是已经很优秀了。感觉可以出成一道很毒瘤的题

先给出普通的\(O(n)\)的代码,而\(O(\sqrt{n})\)的我们将在下一题中用到:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,mu[100100],pri[100100],res;
void getmu(int N){
	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=1;i<=N;i++)mu[i]+=mu[i-1]; 
}
signed main(){
	scanf("%lld%lld",&n,&m),getmu(min(n,m));
	for(int i=1;i<=min(n,m);i++){
		int x=n/i,y=m/i,lim=min(x,y),sum=0;
		for(int l=1,r;l<=lim;l=r+1)r=min(x/(x/l),y/(y/l)),sum+=(x/l)*(y/l)*(mu[r]-mu[l-1]);
		res+=2*i*sum;
	}
	res-=n*m;
	printf("%lld\n",res);
	return 0;
}

标签:nm,min,dfrac,sum,mu,采集,NOI2010,dx,能量
来源: https://www.cnblogs.com/Troverld/p/14619536.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有