您的位置:首页 > 产品设计 > UI/UE

【欧拉函数表】POJ2478-Farey Sequence

2016-05-30 23:42 323 查看
【题目大意】

求∑φ(i)(1<=i<=N)。

【思路】

欧拉函数具有如下的重要推论:


当b是素数时

性质①若b|a,有φ(ab)=φ(a)*b;

性质②若b不|a,有φ(ab)=φ(a)*(b-1)。


由此可以得出递推求欧拉函数表的方法:


对于当前φ(i),若未被修改过,这说明它是素数,加入素数表。

对于每个i,枚举小于它的所有素数j。利用性质1和性质2求出φ(ij)



#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN=1000000+50;
typedef long long ll;
int n,maxn;
int phi[MAXN],p[MAXN],input[MAXN];
ll s[MAXN];
int t=0;

void eular_table()
{
memset(phi,0,sizeof(phi));
memset(p,0,sizeof(p));
p[0]=1;p[1]=2;phi[2]=1;
for (int i=2;i<=maxn;i++)
{
if (phi[i]==0)
{
p[++p[0]]=i;
phi[i]=i-1;
}
for (int j=1;j<=p[0];j++)
{
if (i*p[j]<=maxn) phi[i*p[j]]=(i%p[j]==0)? phi[i]*p[j] : phi[i]*(p[j]-1);
//注意一定要保证i*p[j]没有超出数组上界,否则RE
else break;
}
}
}

void printans()
{
s[0]=0;
for (int i=1;i<=maxn;i++)
s[i]=s[i-1]+phi[i];
for (int i=0;i<t;i++)
printf("%lld\n",s[input[i]]);
}

int main()
{
while (~scanf("%d",&n) && n!=0)
{
input[t++]=n;
maxn=max(maxn,n);
}
eular_table();
printans();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: