SPOJ-VLATTICE Visible Lattice Points-莫比乌斯反演
生活随笔
收集整理的這篇文章主要介紹了
SPOJ-VLATTICE Visible Lattice Points-莫比乌斯反演
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
需要將問(wèn)題分解一下。
我們需要求的是這個(gè)立方體從(0,0,0)能看到的點(diǎn)的個(gè)數(shù)。可是在三個(gè)含有(0,0,0)的面上我們沒(méi)有辦法和其他的一起進(jìn)行分析(因?yàn)楹凶鴺?biāo)是0,而我們的數(shù)論工具都是從1開(kāi)始的),所以我們可以將那三個(gè)面分開(kāi)考慮,剩下的就是一個(gè)立方體,這個(gè)立方體中能看到的點(diǎn)的坐標(biāo)就是gcd(x,y,z)=1,然后用莫比烏斯反演進(jìn)行處理。對(duì)于那三個(gè)面,首先是三個(gè)坐標(biāo)軸上我們只能看到三個(gè)點(diǎn),剩下的每個(gè)面中我們只能看到gcd(x,y)=1的點(diǎn),也用莫比烏斯反演處理。
AC代碼
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<cmath> #include<ctime> #include<climits> #include<queue> #include<vector> #include<set> #include<map> using namespace std;typedef long long ll; const int INF=0x3f3f3f3f; const int MAXN=1e6+5; int prime[MAXN],mobius[MAXN],sum[MAXN]; bool check[MAXN]; int tot;void pre() {tot=0; mobius[1]=1; sum[1]=1;for(int i=2;i<MAXN;i++){if(!check[i]){prime[tot++]=i; mobius[i]=-1;}for(int j=0;j<tot && prime[j]*i<MAXN;j++){check[prime[j]*i]=true;if(i%prime[j]) mobius[prime[j]*i]=-mobius[i];else{mobius[prime[j]*i]=0; break;}}sum[i]=sum[i-1]+mobius[i];} }int main() {pre();int T,n;scanf("%d",&T);while(T--){ll ans=3;scanf("%d",&n);int l,r;for(l=1;l<=n;l=r+1){r=n/(n/l);ans+=(ll)(sum[r]-sum[l-1])*(n/l)*(n/l)*(n/l);ans+=(ll)(sum[r]-sum[l-1])*(n/l)*(n/l)*3;}printf("%lld\n",ans);}return 0; }總結(jié)
以上是生活随笔為你收集整理的SPOJ-VLATTICE Visible Lattice Points-莫比乌斯反演的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 成都大熊猫繁育基地残疾人免费吗
- 下一篇: BZOJ3884上帝与集合的正确用法-欧