1. 程式人生 > >hdu4556(尤拉函式)

hdu4556(尤拉函式)

把樹從中間隔開,只看前一半,然後第n行的分子分母大於n的數去掉,明顯這裡的個數是法裡數列,也就是0到1的最簡真分數的個數,而當法裡數列a[n]=k的時候,a[n+1]=a[n]+phi[n+1]=k+phi[n+1],其中phi[n+1]是n+1的尤拉函式值,這也很明顯,n+1尤拉函式值是1-----n+1與n+1互質的數的個數,則所有1到n+1與n+1互質的數都可以和n+1組成最簡真分數,並且都屬於n+1法裡數列的元素。

因此我們只需要用篩法求出資料範圍內的尤拉函式值就可以了

#include <cstdio>
#include <set>
#include <string>
#include <cstring>
#include <algorithm>
#define LL __int64
#define MM 1000010
using namespace std;
LL phi[MM],a[MM];
void init()
{
	int i,j;
	for(i=1;i<MM;i++)
		phi[i]=i;
	for(i=2;i<MM;i++)
	{
		if(phi[i]==i)
		{
			for(j=i;j<MM;j+=i)
				phi[j]=phi[j]/i*(i-1);
		}
	}
	a[1]=2;
	a[2]=3;
	for(i=3;i<MM;i++)
		a[i]=a[i-1]+phi[i];
}
int main()
{
    int n;
	init();
    //freopen("D://p.txt","r",stdin);
	while(~scanf("%d",&n))
		printf("%I64d\n",a[n]*2-1);
    return 0;
}