分析:令f(x)为1到n的gcd(i,j)==x的个数
F(x)为1到n的x|gcd(i,j)的对数
显然F(n)=∑n|df(d)
然后由莫比乌斯反演可得f(n)=∑n|d μ(d/n)*F(d)
由题目显然可得,令cnt=n/x,当cnt<3时,F(x)为0,cnt>=3,F(x)=cnt*(cnt-1)*(cnt-2)/6
然后就是暴力,复杂度,O(T*n)
注:题目链接https://icpc.njust.edu.cn/Problem/Local/1923/
#include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> using namespace std; typedef long long LL; const int N=1e5+5; int n,m,T,prime[N],mu[N]; bool vis[N]; void getmu() { mu[1] = 1; int cnt = 0; for(int i=2; i<=N-5; i++) { if(!vis[i]) { prime[cnt++] = i; mu[i] = -1; } for(int j=0; j<cnt&&i*prime[j]<=N-5; j++) { vis[i*prime[j]] = 1; if(i%prime[j]) mu[i*prime[j]] = -mu[i]; else { mu[i*prime[j]] = 0; break; } } } } LL F(int x){ LL tmp=n/x; if(tmp<3)return 0; return tmp*(tmp-1)/2*(tmp-2)/3; } int main(){ getmu(); scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); LL ans=0; for(int i=1;i*m<=n;++i){ ans+=mu[i]*F(i*m); } printf("%lld\n",ans); } return 0; }
时间: 2024-10-11 10:57:57