P2257 YY的GCD

题目

求:

\[\large \sum\limits_{k\ is\ prime}\sum\limits_{i=1}^n\sum\limits_{j=1}^m[\gcd(i,j)=k] \]

P2257 YY的GCD

分析

根据结论,那么直接把后半写成:

\[\large \sum\limits_{k\ is\ prime}\sum\limits_{k|d} \mu(\frac{d}{k}) \lfloor\dfrac nd\rfloor\lfloor \dfrac md\rfloor \]

然后转为枚举 \(d\)

\[\large \sum\limits_{d=1}^{\min(n,m)} \lfloor\dfrac nd\rfloor\lfloor \dfrac md\rfloor\sum\limits_{k\mid d,k\ is\ prime}\mu(\frac{d}{k}) \]

那么最后那个柿子可以通过一点小办法处理出来,然后前面就是整除分块。

后面那个可以这样做:考虑每一个质数 \(k\) ,对于 \(k\) 的倍数 \(T\) ,将它的值加上 $ \mu(\frac{T}{k})$

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define inc(x,y,mod) (((x)+(y))>=(mod)?(x)+(y)-(mod):(x)+(y))
#define dec(x,y,mod) ((x)-(y)<0?(x)-(y)+(mod):(x)-(y))
#define rep(i,x,y) for(int i=(x);i<=(y);i++)
#define dep(i,y,x) for(int i=(y);i>=(x);i--)
const int N=1e7+5,M=2e5+5,MOD=1e9+7;
int n,m,k;
int prime[N],mu[N],cnt,pre[N];
ll val[N],Ans;
bool isprime[N];
void GetPrimes(int v){
	mu[1]=1;
	for(int i=2;i<=v;i++){
		if(!isprime[i]) prime[++cnt]=i,mu[i]=-1;
		for(int j=1;j<=cnt&&prime[j]*i<=v;j++){
			isprime[i*prime[j]]=true;
			if(i%prime[j]==0) break;
			mu[i*prime[j]]=-mu[i];
		}
	}
	for(int i=1;i<=cnt;i++) for(int j=1;j*prime[i]<=v;j++) val[j*prime[i]]+=mu[j];
	for(int i=1;i<=v;i++) val[i]+=val[i-1];
	return ;
}
signed main(){
	ios::sync_with_stdio(false);
	GetPrimes(1e7);
	int t;cin>>t;
	while(t--){
		cin>>n>>m;Ans=0;
		if(n<m) swap(n,m);
		for(int l=1,r;l<=m;l=r+1){
			r=min(n/(n/l),m/(m/l));
			Ans+=1ll*(val[r]-val[l-1])*(n/(l))*(m/(l));
		}
		cout<<Ans<<endl;
	}
	return 0;
}



posted @ 2021-08-30 21:00  __Anchor  阅读(42)  评论(0编辑  收藏  举报