SPOJ 7001 Visible Lattice Points (莫比乌斯反演+分块)

来源:互联网 发布:麦克风测试软件汉化 编辑:程序博客网 时间:2024/06/05 17:57

思路:

跟bzoj 2190差不多,这道题是那个的升级版,这个变成了三维的。
思路一模一样。
算完三维的,记得加上3个剩下的2维的平面上点的贡献就好。

#include<stdio.h>#include <iostream>#include<string.h>#include<math.h>#include<algorithm>#define eps 1e-8typedef long long int lli;using namespace std;const int maxn = 1e6+10;bool isprime[maxn];int prime[maxn];char miu[maxn];void moblus(){    int cnt = 0;miu[1] = 1;    for(lli i = 2;i < maxn;i++){        if(!isprime[i]){            prime[cnt++] = i,miu[i] = -1;//phi[i] = i-1;        }        for(lli j = 0;j < cnt && i*prime[j] < maxn;j++){            lli x = prime[j];            isprime[i*x] = 1;            if(i%x){                miu[i*x] = -miu[i];                //phi[i*x] = phi[i] * phi[x];            }            else{                miu[i*x] = 0;                //phi[i*x] = phi[i] * x;                break;            }        }    }}int ff[maxn],sum[maxn];int main(){    lli q;    scanf("%lld",&q);    moblus();    for(int i = 1;i <= maxn;i++){        sum[i] = sum[i-1] + miu[i];    }    while(q--){        lli a,b;        scanf("%lld",&a);        lli ans = 0,l;        for(int i = 1;i <= 1;i++){            lli n = a/i;            for(int j=1;j<=n;j=l+1){//分块加速                l= n/(n/j);                ans += (lli)(sum[l]-sum[j-1])*(n/j)*(n/j)*(n/j);            }        }        lli n = a,tempans = 0;        for(int j=1;j<=n;j=l+1){//分块加速            l= n/(n/j);            tempans += (lli)(sum[l]-sum[j-1])*(n/j)*(n/j);        }        printf("%lld\n",ans+3*tempans+3);    }    return 0;}
阅读全文
0 0
原创粉丝点击