【BZOJ 2005】【NOI 2010】能量采集 数论+容斥原理

这题设$f(i)$为$gcd(i,j)=x$的个数,根据容斥原理,我们只需减掉$f(i×2),f(i×3)cdots$即可

那么这道题:$$ans=sum_{i=1}^n(f(i)×((i-1)×2+1))$$

注意要开$longlong$,否则会炸

#include<cstdio>
#include<algorithm>
using namespace std;
long long f[100003];
int main(){
	int n,m;
	long long k=0;
	scanf("%d %d
",&n,&m);
	if (n>m)
		swap(n,m);
	for(int i=n;i>=1;--i){
		f[i]=(long long)(n/i)*(m/i);
		for(int j=i+i;j<=n;j+=i)
			f[i]-=f[j];
		k+=f[i]*i*2-f[i];
	}
	printf("%lld
",k);
	return 0;
}

这样就行啦

zky学长讲的$O(n+sqrt{n})$的快速筛积性函数的方法:

[ egin{aligned} ans & = sum_{i=1}^n sum_{j=1}^m gcd(i,j) \ & = sum_{i=1}^n sum_{j=1}^m sum_{k=1}^n k[k|i][k|j][gcd(frac{i}{k},frac{j}{k})=1] \ & = sum_{k=1}^n k sum_{i=1}^n sum_{j=1}^m [k|i][k|j][gcd(frac{i}{k},frac{j}{k})=1] \ & i=ki, j=kj \ & = sum_{k=1}^n k sum_{i=1}^{left lfloor frac{n}{k} ight floor} sum_{j=1}^{left lfloor frac{m}{k} ight floor} [ gcd(i,j)=1] \ & = sum_{k=1}^n k sum_{i=1}^{left lfloor frac{n}{k} ight floor} sum_{j=1}^{left lfloor frac{m}{k} ight floor} sum_{d=1}^{left lfloor frac{n}{k} ight floor} [d|i][d|j] mu(d) \ & = sum_{k=1}^n k sum_{d=1}^{left lfloor frac{n}{k} ight floor} mu(d) sum_{i=1}^{left lfloor frac{n}{k} ight floor} sum_{j=1}^{left lfloor frac{m}{k} ight floor} [d|i][d|j] \ & =  sum_{k=1}^n k sum_{d=1}^{left lfloor frac{n}{k} ight floor} mu(d) left lfloor frac{n}{dk} ight floor left lfloor frac{m}{dk} ight floor \ & T=dk \ & = sum_{T=1}^n left lfloor frac{n}{T} ight floor left lfloor frac{m}{T} ight floor sum_{d|T} mu(d) frac{T}{d} \ end{aligned}]

xyx说因为$sum_{d|T} mu(d) frac{T}{d}$(及$id×mu$)是积性的,所以筛一筛就出来啦

无限仰膜O)Z   OSZ   OTZ

这个方法我就先不写了,因为我太蒟蒻有可能推错了,如果哪位神犇发现错误请指出来,万分感谢!!!

2016-03-30:达神的正解!上面那个看一眼就觉得纯属扯淡(没事莫比乌斯反演干什么):$(n<m)$

[ egin{aligned} ans & = sum_{i=1}^n sum_{j=1}^m gcd(i,j) \ & = sum_{i=1}^n sum_{j=1}^m sum_{d=1}^n [d|i][d|j]  phi(d) \ & = sum_{d=1}^n sum_{i=1}^n sum_{j=1}^m [d|i][d|j] phi(d) \ & = sum_{d=1}^n left lfloor frac{n}{d} ight floor left lfloor frac{m}{d} ight floor phi(d) end{aligned} ]

原文地址:https://www.cnblogs.com/abclzr/p/5301846.html