spoj7001. Visible Lattice Poin

来源:互联网 发布:手机大型网络枪战游戏 编辑:程序博客网 时间:2024/06/01 09:28
Consider a N*N*N lattice. One corner is at (0,0,0) and the opposite one is at (N,N,N). How many lattice points are visible from corner at (0,0,0) ? A point X is visible from point Y iff no other lattice point lies on the segment joining X and Y. 
 
Input : 
The first line contains the number of test cases T. The next T lines contain an interger N 
 
Output : 
Output T lines, one corresponding to each test case. 
 
Sample Input : 




 
Sample Output : 

19 
175 
 
Constraints : 
T <= 50 

1 <= N <= 1000000


这题就是求gcd(a,b,c) = 1    a,b,c <=N 的对数。

 

用莫比乌斯反演可以求解。

g(n)gcd(x,y,z)=n的个数,f(n)n | g(i*n)的个数,那么有f(n)=sigma(n|d,g(d)),那么g(n)=sigma(n|d, mu(d/n)*f(d)),我们要求g(1),则g(1)=sigma(n|d, mu(d)*f(d))

因为f(d)=(n/d)*(n/d)*(n/d),所以g(1)=sigma( mu(d)*(n/d)*(n/d)*(n/d) ).


#include<iostream>#include<cstring>#include<cstdio>#include<ostream>#include<istream>#include<algorithm>#include<queue>#include<string>#include<cmath>#include<set>#include<map>#include<stack>#include<vector>#define fi first#define se second#define ll long long#define pii pair<int,int>#define inf (1<<30)#define eps 1e-8#define pb push_backusing namespace std;const int maxn=1000010;int n;int mu[maxn],prime[maxn],tot;bool check[maxn];void getmu(){    int N=1000000;    memset(check,0,sizeof(check));    mu[1]=1,tot=0;    for(int i=2;i<=N;i++){        if(!check[i])            prime[tot++]=i,mu[i]=-1;        for(int j=0;j<tot;j++){            if(i*prime[j]>N)                break;            check[i*prime[j]]=true;            if(i%prime[j]==0){                mu[i*prime[j]]=0;                break;            }            else                mu[i*prime[j]]=-mu[i];        }    }}int main(){    getmu();    int t;    scanf("%d",&t);    while(t--) {        scanf("%d",&n);        ll ans=3;        for(int i=1;i<=n;i++) {            ans+=(ll)mu[i]*(n/i)*(n/i)*(n/i)+(ll)mu[i]*(n/i)*(n/i)*3;        }        printf("%lld\n",ans);    }    return 0;}


0 0
原创粉丝点击