SPOJ 7001 VLATTICE - Visible Lattice Points(莫比乌斯反演)
2016-08-03 12:49
337 查看
Description
求经过坐标(0,0,0)和另外任意一个点(x1,y1,z1)的不同的直线有多少条(0<=x1,y1,z1<=n)
Input
第一行为一整数T表示用例组数,每组用例占一行为一整数n(T<=50,1<=n<=1000000)
Output
对于每组用例,输出经过坐标(0,0,0)和另外任意一个点(x1,y1,z1)的不同的直线有多少条
Sample Input
3
1
2
5
Sample Output
7
19
175
Solution
3种情况
1. x1,y1,z1都大于等于1,问题变成求1<=x<=n,1<=y<=n,1<=z<=n,gcd(x,y,z)=1的三元组有多少对
2. x1,y1,z1中有1个为0,问题退化成2维的互质问题了
3. x1,y1,z1中有2个为0,只有三个坐标轴满足
所以答案就是3+3*f(n,n)+g(n,n,n)
其中f(a,b)表示1<=i<=a,1<=j<=b,gcd(i,j)=1的(i,j)对数
g(a,b,c)表示1<=i<=a,1<=j<=b,1<=k<=c,gcd(i,j,k)=1的(i,j,k)对数
Code
求经过坐标(0,0,0)和另外任意一个点(x1,y1,z1)的不同的直线有多少条(0<=x1,y1,z1<=n)
Input
第一行为一整数T表示用例组数,每组用例占一行为一整数n(T<=50,1<=n<=1000000)
Output
对于每组用例,输出经过坐标(0,0,0)和另外任意一个点(x1,y1,z1)的不同的直线有多少条
Sample Input
3
1
2
5
Sample Output
7
19
175
Solution
3种情况
1. x1,y1,z1都大于等于1,问题变成求1<=x<=n,1<=y<=n,1<=z<=n,gcd(x,y,z)=1的三元组有多少对
2. x1,y1,z1中有1个为0,问题退化成2维的互质问题了
3. x1,y1,z1中有2个为0,只有三个坐标轴满足
所以答案就是3+3*f(n,n)+g(n,n,n)
其中f(a,b)表示1<=i<=a,1<=j<=b,gcd(i,j)=1的(i,j)对数
g(a,b,c)表示1<=i<=a,1<=j<=b,1<=k<=c,gcd(i,j,k)=1的(i,j,k)对数
Code
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; #define maxn 1111111 #define INF 0x3f3f3f3f typedef long long ll; bool check[maxn]; int prime[maxn],mu[maxn],sum[maxn]; void Moblus(int n) { memset(check,0,sizeof(check)); mu[1]=1; int 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]]=1; if(i%prime[j]==0) { mu[i*prime[j]]=0; break; } else mu[i*prime[j]]=-mu[i]; } } sum[0]=0; for(int i=1;i<maxn-10;i++)sum[i]=sum[i-1]+mu[i]; } ll f(int a,int b) { if(a>b)swap(a,b); ll ans=0; for(int i=1,next=0;i<=a;i=next+1) { next=min(a/(a/i),b/(b/i)); ans+=1ll*(a/i)*(b/i)*(sum[next]-sum[i-1]); } return ans; } ll g(int a,int b,int c) { if(a>b)swap(a,b); if(a>c)swap(a,c); ll ans=0; for(int i=1,next=0;i<=a;i=next+1) { next=min(a/(a/i),min(b/(b/i),c/(c/i))); ans+=1ll*(a/i)*(b/i)*(c/i)*(sum[next]-sum[i-1]); } return ans; } int main() { Moblus(maxn-10); int T,n; scanf("%d",&T); while(T--) { scanf("%d",&n); ll ans=3+3*f(n,n)+g(n,n,n); printf("%lld\n",ans); } return 0; }
相关文章推荐
- spoj 7001 VLATTICE - Visible Lattice Points(莫比乌斯反演)
- SPOJ 7001 VLATTICE - Visible Lattice Points(莫比乌斯反演)
- SPOJ VLATTICE Visible Lattice Points (莫比乌斯反演基础题)
- SPOJ - VLATTICE Visible Lattice Points (莫比乌斯反演)
- SPOJ - VLATTICE Visible Lattice Points(gcd(x,y,z)=1的对数/莫比乌斯反演)
- [SPOJ VLATTICE]Visible Lattice Points 数论 莫比乌斯反演
- SPOJ VLATTICE Visible Lattice Points - 莫比乌斯反演
- SPOJ 7001 Visible Lattice Points(莫比乌斯反演)
- SPOJ 7001 Visible Lattice Points (莫比乌斯反演)
- VLATTICE - Visible Lattice Points [Spoj 7001]
- SPOJ VLATTICE Visible Lattice Points(莫比乌斯反演入门)
- SPOJ VLATTICE Visible Lattice Points (莫比乌斯反演基础题)
- SPOJ 7001 Visible Lattice Points (莫比乌斯反演)
- SPOJ 7001 Visible Lattice Points(莫比乌斯反演)
- SPOJ VLATTICE Visible Lattice Points (莫比乌斯反演)
- SPOJ VLATTICE - Visible Lattice Points 莫比乌斯反演
- SPOJ VLATTICE - Visible Lattice Points 莫比乌斯反演
- SPOJ1007 VLATTICE - Visible Lattice Points
- spoj 7001 Visible Lattice Points
- [SPOJ VLATTICE]Visible Lattice Points 数论 莫比乌斯反演