P3455 [POI 2007] ZAP-Queries

P3455 [POI 2007] ZAP-Queries - Description

\(T\) 组询问,每次给定正整数 \(n,m,d\),求

\[\sum_{i=1}^n\sum_{j=1}^m \left [ \gcd(i,j)=d \right ] \]

\(1\le T,n,m,d\le 5\times 10^4\)

P3455 [POI 2007] ZAP-Queries - Solution

\[\begin{aligned} \sum_{i=1}^n\sum_{j=1}^m \left [ \gcd(i,j)=d \right ]&= \sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d} \rfloor} \left [ \gcd(i,j)=1 \right ]\\&= \sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d} \rfloor} \sum_{k\mid \gcd(i,j)} \mu(k)\\&= \sum_{k=1}^n \mu(k)\sum_{k\mid i}^{\lfloor \frac{n}{d} \rfloor}\sum_{k\mid j}^{\lfloor \frac{m}{d}\rfloor}1\\&= \sum_{k=1}^n \mu(k) \lfloor \frac{\lfloor \frac{n}{d} \rfloor}{k} \rfloor \lfloor\frac{\lfloor\frac{m}{d}\rfloor}{k}\rfloor\\&= \sum_{k=1}^n \mu(k) \lfloor \frac{n}{kd} \rfloor \lfloor\frac{m}{kd}\rfloor \end{aligned} \]

考虑预处理出 \(\mu\) 函数,后面的二维整除分块即可,时间复杂度 \(O(T\sqrt{n})\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
long long T,n,m,d,ans;
long long Prime[50005],mu[50005],vis[50005],tot;
long long summu[50005];
inline void init(){
	vis[1]=1;
	mu[1]=1;
	for(int i=2;i<=50000;i++){
		if(!vis[i]){
			Prime[++tot]=i;
			mu[i]=-1;
		}
		for(int j=1;j<=tot&&i*Prime[j]<=50000;j++){
			vis[i*Prime[j]]=1;
			if(i%Prime[j]==0){
				mu[i*Prime[j]]=0;
				break;
			}
			mu[i*Prime[j]]=-mu[i];
		}
	}
	for(int i=1;i<=50000;i++){
		summu[i]=summu[i-1]+mu[i];
	}
	return;
}
signed main(){
	cin>>T;
	init();
	while(T--){
		ans=0;
		cin>>n>>m>>d;
		int qwq=min(n,m);
		int r=1;
		for(int l=1;l<=qwq/d;l=r+1){
			r=min((n/d)/((n/d)/l),(m/d)/((m/d)/l));
			int tmp=(n/d)/(l)*((m/d)/(l));
			ans+=(summu[r]-summu[l-1])*(tmp);
		}
		cout<<ans<<endl;
	}
	return 0;
}
posted @ 2026-01-08 21:24  Creativexz  阅读(7)  评论(0)    收藏  举报