luoguP2257 YY的GCD

题意

\(f(d)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[\gcd(i,j)=d],F(d)=\sum\limits_{k|d}f(k)=\frac{n}{d}*\frac{m}{d}\)

得:
\(f(n)=\sum\limits_{n|d}\mu(\frac{d}{n})F(d)\)

\(ans=\sum\limits_{p\in prime}f(p)\)
\(=\sum\limits_{p\in prime}\sum\limits_{p|d}\mu(\frac{d}{p})*F(d)\)
\(\frac{d}{p}=t\)
\(=\sum\limits_{p\in prime}\sum\limits_{t=1}^{min(\frac{n}{p},\frac{m}{p})}\mu(t)*F(t*p)\)
\(=\sum\limits_{p\in prime}\sum\limits_{t=1}^{min(\frac{n}{p},\frac{m}{p})}\mu(t)*\frac{n}{t*p}*\frac{m}{t*p}\)
\(t*p=T\)
\(=\sum\limits_{T=1}^{min(n,m)}\sum\limits_{t|T,t\in prime}\mu(\frac{T}{t})*\frac{n}{T}*\frac{m}{T}\)
\(=\sum\limits_{T=1}^{min(n,m)}\frac{n}{T}*\frac{m}{T}*(\sum\limits_{t|T,t\in prime}\mu(\frac{T}{t}))\)

于是就可以做了。

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=10000010;
int T,n,m;
int mu[maxn],sum[maxn];
bool vis[maxn];
vector<int>prime;
inline void shai(int n)
{
	vis[1]=1;mu[1]=1;
	for(int i=2;i<=n;i++)
	{
		if(!vis[i])prime.push_back(i),mu[i]=-1;
		for(unsigned int j=0;j<prime.size()&&i*prime[j]<=n;j++)
		{
			vis[i*prime[j]]=1;
			if(i%prime[j]==0){mu[i*prime[j]]=0;break;}
			mu[i*prime[j]]=-mu[i];
		}
	}
	for(unsigned int i=0;i<prime.size();i++)
		for(int j=1;j*prime[i]<=n;j++)
			sum[j*prime[i]]+=mu[j];
	for(int i=1;i<=n;i++)sum[i]+=sum[i-1];
}
inline ll solve(int n,int m)
{
	ll res=0;
	for(int l=1,r;l<=min(n,m);l=r+1)
	{
		r=min(n/(n/l),m/(m/l));
		res+=1ll*(n/l)*(m/l)*(sum[r]-sum[l-1]);
	}
	return res;
}
int main()
{
	shai(10000000);
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		printf("%lld\n",solve(n,m));
	}
	return 0;
}
posted @ 2019-11-27 09:29  nofind  阅读(78)  评论(0编辑  收藏  举报