POJ 3090 Visible Lattice Points(莫比乌斯反演)

来源:互联网 发布:java大数据处理技术 编辑:程序博客网 时间:2024/06/10 14:17

题目链接
题意:给出一个n*n的格点,从原点发射出的光线,能够照到的点的个数。 其实就是计算gcd==1 和gcd==0(2个坐标轴)

gcd==1直接莫比乌斯反演做好了,小数据不用分块优化也可以

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;#define cl(a,b) memset(a,b,sizeof(a))#define ll long long#define pb push_back#define gcd __gcdconst double EPS = 1e-8;const int maxn = 1e3+1000;const int inf  = 0x3f3f3f3f;const double PI = acos(-1.0);bool check[maxn];int prime[maxn];int mu[maxn];void Moblus(){    cl(check,false);    mu[1]=1;int tot=0;    for(int i=2;i<maxn;i++){        if(!check[i]){            prime[tot++]=i;            mu[i]=-1;        }        for(int j=0;j<tot;j++){            if(i*prime[j]>maxn)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 k;//TLE 代码ll cal(int n,int m){    n/=k;m/=k;    if(n>m)swap(n,m);    ll ans=0;    for(int i=1;i<=n;i++)ans+=(ll)mu[i]*(n/i)*(m/i);    return ans;}*/ll sum[maxn];//分块优化 N/x值的种类个数不大于2*sqrt(N)//计算[1,n],[1,m]互质的对数ll cal(int n,int m){    if(n>m)swap(n,m);    ll ans=0;    for(int i=1,last=0;i<=n;i=last+1){        last=min(n/(n/i),m/(m/i));        ans+=(sum[last]-sum[i-1])*(n/i)*(m/i);    }    return ans;}int main(){    Moblus();    sum[0]=0;for(int i=1;i<maxn;i++)sum[i]=sum[i-1]+mu[i];    int T;scanf("%d",&T);    int cas=1;    while(T--){        int n;scanf("%d",&n);        printf("%d %d %lld\n",cas++,n,cal(n,n)+2);//gcd==1 and gcd ==0     }    return 0;}
0 0
原创粉丝点击