YY的GCD(莫比乌斯反演)

Posted thusloop

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了YY的GCD(莫比乌斯反演)相关的知识,希望对你有一定的参考价值。

YY的GCD
题意:求 i<=n,j<=m 的对数使得gcd(i,j)==p且p为质数

//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf=2e18+100;
const int maxn=1e7+100;
bool vis[maxn];
int pri[maxn],len,mu[maxn],sum[maxn],pre[maxn];
void init()
{
	mu[1]=1;
	for(int i=2;i<maxn;i++)
	{
		if(!vis[i])
		{
			pri[++len]=i;
			mu[i]=-1;
		}
		for(int j=1;j<=len&&pri[j]*i<maxn;j++)
		{
			vis[i*pri[j]]=1;
			if(i%pri[j]==0)
			{
				mu[i*pri[j]]=0;
				break;
			}
			mu[i*pri[j]]=-mu[i];
		}
	}  
//  莫比乌斯函数↑↑↑↑↑↑↑↑↑ 	
//-------------------------------------------
//  预处理  ↓↓↓↓↓↓↓↓↓↓↓
    for(int i=1;i<=len;i++)
    {
		for(int j=1;j*pri[i]<maxn;j++)
		{
			sum[j*pri[i]]+=mu[j];
		}
	}	
	for(int i=1;i<maxn;i++)
	{
		pre[i]=pre[i-1]+sum[i];
	}
}
signed main()
{
	IOS
	init();
	int tt;
	cin>>tt;
	while(tt--)
	{
		int N,M;
		cin>>N>>M;
		int ans=0;
		for(int l=1,r;l<=min(N,M);l=r+1)
		{
			r=N/(N/l);
			r=min(r,M/(M/l));
			ans+=(M/l)*(N/l)*(pre[r]-pre[l-1]);
		}
		cout<<ans<<"\\n";
	}
}

以上是关于YY的GCD(莫比乌斯反演)的主要内容,如果未能解决你的问题,请参考以下文章

P2257 YY的GCD (莫比乌斯反演)

BZOJ2820YY的GCD(莫比乌斯反演)

luogu2658 GCD(莫比乌斯反演/欧拉函数)

P2257 YY的GCD莫比乌斯反演

P2257 YY的GCD莫比乌斯反演

P2257 YY的GCD莫比乌斯反演