在昨天的比赛中,A题中,有一道题,与法雷级数很是相似。但是,强大的队友们还是给推出来,是欧拉函数。ORZ。
法雷级数:
所有分母小于等于n,并且值介于0到1之间的既约分数(分子分母互素)从小到大排列所组成的序列 。
即 Fn = { a / b, gcd(a,b) = 1 && 0<=a<=b<=n};
如下:
F1 = { 0 / 1, 1 / 1 };
F2 = { 0 / 1, 1 / 2, 1 / 1 };
F3 = { 0 / 1, 1 / 3, 1 / 2, 2 / 3, 1 / 1 };
那么一般情况下,我们都想要知道,Fn有多少个?
我们知道Fn中,相对于Fn-1,增加的就是以n为分母的元素。那么,增加的个数就是从1-n互素的个数。也就是欧拉函数。
这里我们设F(n)就是Fn的个数,E(n)为欧拉函数的值。那么结论就是:
F(n)=F(n-1)+E(n);
性质:
第一,如果a / b, a’ / b’是Fn中相邻的两项,则有abs(a * b’ – b * a’) = 1。
第二,如果a / b, a’’ / b’’, a’ / b’是Fn中的相邻三项,则有( a + a’ ) / ( b + b’ ) = a’’ / b’’。
特别地,如果a’’ / b’’是新添加的,即a’’ / b’’不属于F(n-1),则有a + a’ = a’’ && b + b’ = b’。
法雷级数推荐题目:poj2478 Farey Sequence
poj3090 Visible Lattice Points
那么,昨天,我们的比赛题目:点击打开链接
题目的意思就是,给一个序列,
f1=1 1.
f2=1 2 1.
f3=1 3 2 3 1.
f4=1 4 3 2 3 4 1.
fn如果相邻的两个数相加为n的话,加入序列。
求解第n个序列的增加了多少个。
可以看到,该序列与法雷级数的分母是一致的。也就是说,每次增加的就是E(n),欧拉函数的值。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define LL long long
using namespace std;
//if(n%a==0&&(n/a)%a==0) then e(n)=e(n/a)*a;
//if(n%a==0&&(n/a)%a!=0) then e(n)=e(n/a)*(a-1);
LL eular(LL n){
LL cnt=1,i;
for(i=2;i*i<=n;i++)
if(n%i==0){
n=n/i;
cnt=cnt*(i-1);
while(n%i==0){
n=n/i;
cnt=cnt*i;
}
}
if(n>1)
cnt=cnt*(n-1);
return cnt;
}
int main(){
LL n,T;
scanf("%lld",&T);
while(T--&&scanf("%lld",&n)){
printf("%lld\n",eular(n));
}
return 0;
}
比赛之前,我们都没有看到过这个法雷级数,但是,竟然,给推出来了。ORZ,队友太给力了。
还有就是,如果对于欧拉函数足够了解的话,那么,推出前几项就可以看出规律了。数论大神,ORZ。