Visible Lattice Points POJ - 3090
2017-08-07 15:34
246 查看
题意:
有一个n*n的点阵,站在(0,0)点,你可以看见(1,1),(1,2),但是你看不见(2,2),(2,4)
因为(2,2)会被(1,1)挡住,(2,4)会被(1,2)挡住
给定n,求能看见的点的个数
思路:
即在n*n范围内,gcd(i,j)=1的数对的个数
想到欧拉函数是[1,n-1]内与n互质的数的个数,
前缀加和
另外这也可以用莫比乌斯反演
我们要求出gcd(a,b)=1的数对个数
F(1)= sigma f(1*k)
f(1)= sigma u(d/1) * f(d*k);
#include<stdio.h>
#include<string.h>
const int MAXN=1000;
bool check[MAXN+10];
int prime[MAXN+10];
int mu[MAXN+10];
void init()
{
memset(check,false,sizeof(check));
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 main()
{
int t,n;
init();
scanf("%d",&t);
for(int j=1;j<=t;j++)
{
scanf("%d",&n);
int ans=2;
for(int i=1;i<=n;i++)
ans+=(long long)mu[i]*(n/i)*(n/i); //莫比乌斯反演 F(i)=(n/i)*(n/i)*(n/i+3) f(i)=sigma F(k*i);
printf("%d %d %d\n",j,n,ans);
}
return 0;
}
总结一下:通过这个题目和 GCD HDU - 2588 都可以看到 某些时间 欧拉函数也完成了容斥的工作
有一个n*n的点阵,站在(0,0)点,你可以看见(1,1),(1,2),但是你看不见(2,2),(2,4)
因为(2,2)会被(1,1)挡住,(2,4)会被(1,2)挡住
给定n,求能看见的点的个数
思路:
即在n*n范围内,gcd(i,j)=1的数对的个数
想到欧拉函数是[1,n-1]内与n互质的数的个数,
前缀加和
#include<stdio.h> #include<string.h> int a[1009]; bool book[1009]; int p[1009]; int ans[1009]; void init() { int i; for(i=1; i<=1009; i++) p[i]=i; for(i=2; i<=1009; i+=2) p[i]/=2; for(i=3; i<=1009; i+=2) if(p[i]==i) { for(int j=i; j<=1009; j+=i) p[j]=p[j]/i*(i-1); } ans[0]=0; ans[1]=3; for(int i=2;i<=1009;i++) ans[i]=ans[i-1]+2*p[i] ; } int main() { int t,n; init(); scanf("%d",&t); for(int i=1;i<=t;i++) { scanf("%d",&n); printf("%d %d %d\n",i,n,ans ); } return 0; }
另外这也可以用莫比乌斯反演
我们要求出gcd(a,b)=1的数对个数
F(1)= sigma f(1*k)
f(1)= sigma u(d/1) * f(d*k);
#include<stdio.h>
#include<string.h>
const int MAXN=1000;
bool check[MAXN+10];
int prime[MAXN+10];
int mu[MAXN+10];
void init()
{
memset(check,false,sizeof(check));
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 main()
{
int t,n;
init();
scanf("%d",&t);
for(int j=1;j<=t;j++)
{
scanf("%d",&n);
int ans=2;
for(int i=1;i<=n;i++)
ans+=(long long)mu[i]*(n/i)*(n/i); //莫比乌斯反演 F(i)=(n/i)*(n/i)*(n/i+3) f(i)=sigma F(k*i);
printf("%d %d %d\n",j,n,ans);
}
return 0;
}
总结一下:通过这个题目和 GCD HDU - 2588 都可以看到 某些时间 欧拉函数也完成了容斥的工作
相关文章推荐
- 数论 - 欧拉函数的运用 --- poj 3090 : Visible Lattice Points
- POJ 3090 Visible Lattice Points 法雷级数
- POJ 3090 Visible Lattice Points | 其实是欧拉函数
- POJ 3090 Visible Lattice Points 笔记
- POJ 3090-Visible Lattice Points(筛选法求欧拉函数)
- poj 3090:Visible Lattice Points
- POJ 3090 Visible Lattice Points(莫比乌斯反演)
- poj 3090 Visible Lattice Points 欧拉函数打表求和
- POJ 3090 Visible Lattice Points
- POJ 3090 Visible Lattice Points (ZOJ 2777)
- POJ 3090 Visible Lattice Points 欧拉函数
- POJ 3090 Visible Lattice Points[]
- POJ 3090 Visible Lattice Points 布雷级数
- poj 3090 Visible Lattice Points
- poj 3090 Visible Lattice Points
- (Relax 数论1.9)POJ 3090 Visible Lattice Points(欧拉函数的应用:计算前n项欧拉数之和)
- POJ 3090 Visible Lattice Points (欧拉函数)
- POJ 3090 Visible Lattice Points
- POJ 3090 Visible Lattice Points (ZOJ 2777)
- POJ 3090 Visible Lattice Points 欧拉函数