zoukankan      html  css  js  c++  java
  • Spoj 7001 Visible Lattice Points 莫比乌斯,分块

     
    Time Limit: 1368MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu

     Status

    Description

    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

    Hint

     
    题意:在一个边长为n的正方体内,从原点出发能够接触多少个点。
     
    题解:
    莫比乌斯反演。
    首先,我们要把答案分三类讨论:
    1, 坐标轴上的三个点可以看见(1,0,0)和(0,1,0)和(0,0,1)。
    2, 与原点相邻的三个表面的点。在三个表面各反演一次,加起来即可。
    3, 在三维空间中反演一次即可。
    答案为三种情况的和。
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define MAXN 1000010
     4 #define LL long long
     5 int mu[MAXN+10],prime[80010],qz[MAXN+10],tot;
     6 bitset<MAXN+10> vis;
     7 int read()
     8 {
     9     int s=0,fh=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
    12     return s*fh;
    13 }
    14 void getmu()
    15 {
    16     int i,j;
    17     mu[1]=1;tot=0;
    18     for(i=2;i<=MAXN;i++)
    19     {
    20         if(vis[i]==0)
    21         {
    22             prime[++tot]=i;
    23             mu[i]=-1;
    24         }
    25         for(j=1;j<=tot&&prime[j]*i<=MAXN;j++)
    26         {
    27             vis[prime[j]*i]=1;
    28             if(i%prime[j]==0)
    29             {
    30                 mu[prime[j]*i]=0;
    31                 break;
    32             }
    33             mu[prime[j]*i]=-mu[i];
    34         }
    35     }
    36 }
    37 void Qz()
    38 {
    39     for(int i=1;i<=MAXN;i++)qz[i]=qz[i-1]+mu[i];
    40 }
    41 LL calc2(int n)//计算平面上的个数.
    42 {
    43     int d,pos;
    44     LL sum=0;
    45     for(d=1;d<=n;d=pos+1)
    46     {
    47         pos=n/(n/d);
    48         sum+=(LL)(qz[pos]-qz[d-1])*(n/d)*(n/d);
    49     }
    50     return sum;
    51 }
    52 LL calc3(int n)//计算空间里的个数.
    53 {
    54     int d,pos;
    55     LL sum=0;
    56     for(d=1;d<=n;d=pos+1)
    57     {
    58         pos=n/(n/d);
    59         sum+=(LL)(qz[pos]-qz[d-1])*(n/d)*(n/d)*(n/d);
    60     }
    61     return sum;
    62 }
    63 int main()
    64 {
    65     int N,T;
    66     T=read();
    67     getmu();
    68     Qz();
    69     while(T--)
    70     {
    71         N=read();
    72         printf("%lld
    ",calc3(N)+calc2(N)*3+3);
    73     }
    74     fclose(stdin);
    75     fclose(stdout);
    76     return 0;
    77 }
    View Code

     

  • 相关阅读:
    用python写爬虫
    ASM上的备份集如何转移到文件系统中
    Web基础知识和技术
    java调用存储过程超时及DBCP参数配置说明
    android JNI--- 搭建环境(1)
    android jni——helloworld
    程序设计的预防与诊断
    [置顶] 某大型银行深化系统技术方案之十七:技术架构
    Ubuntu12.04 Eclipse 提示框背景色修改
    window与linux互相拷贝文件
  • 原文地址:https://www.cnblogs.com/Var123/p/5285053.html
Copyright © 2011-2022 走看看