题目链接
SPOJ - VLATTICE-莫比乌斯反演
思路
首先这题很容易转成
因为如果gcd(i,j,k)=g≠1,则必有gcd(i/g,j/g,k/g)=1;
然后用莫比乌斯反演套路直接设
设f(n)为gcd(a,b,c)=n的个数
则F(n)为gcd(a,b,c)=n及n的倍数的个数
则有
然后用莫比乌斯倍数反演得到
然后f(1)就是我们要求的答案,显而易见
然后。
但是这题有特殊情况,在面上时相当于二维,也就是
;
所以把他们两个加起来就好了
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include<bits/stdc++.h> using namespace std; #define ll long long const int maxn = 1e6+10; int mu[maxn]; bool vis[maxn]; int prime[maxn],cnt; int F[maxn]; void get_mu(){ mu[1]=1; for(int i=2;i<maxn;i++) { if(!vis[i]) { prime[cnt++]=i; mu[i]=-1; } for(int j=0;j<cnt&&prime[j]*i<maxn;j++) { vis[i*prime[j]]=true; if(i%prime[j]) { mu[i*prime[j]]=-mu[i]; } else { mu[i*prime[j]]=0; break; } } } } int main() { get_mu(); int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); ll ans = 3; for(int i=1;i<=n;i++) { ans+=1ll*mu[i]*(n/i)*(n/i)*(n/i+3); } printf("%lld\n",ans); } }
|
你最愿意做的哪件事,才是你的天赋所在