[欧拉函数]法雷级数

题面描述

法雷级数Fi的定义如下:
给定一个i(i>=2),那么所有的 a/b (0<a<b<=i 且 gcd(a,b)==1 )组成了Fi,
例如:
F2 = {1/2}
F3 = {1/3, 1/2, 2/3}
F4 = {1/4, 1/3, 1/2, 2/3, 3/4}
F5 = {1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5}
你的任务就是统计对于给出的i,Fi集合的元素个数。
【输入格式】
第一行n(1<=n<=10000)
下来n行,每行一个整数x,表示求Fx的元素个数。(1<=x<=2000 0000)
【输出格式】
每次询问输出一行一个整数,即Fx的元素个数。
【样例输入】
4
2
3
4
5
【样例输出】
1
3
5
9

思路

观察可以发现 f [ i ] = f [ i − 1 ] + p h i [ i ] f[i]=f[i-1]+phi[i] f[i]=f[i1]+phi[i],实际上对于 x y \frac{x}{y} yx是最简真分数,当且仅当 x , y x,y x,y互质, y &gt; x y&gt;x y>x;则对于每一个 y y y,满足条件的 x x x的个数即为 φ ( x ) \varphi(x) φ(x)。即 f [ i ] f[i] f[i]实质上就是 ∑ j = 2 i φ ( j ) \sum_{j=2}^i\varphi(j) j=2iφ(j)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<bitset>
#define ll long long
using namespace std;
const int N=2e7+10;
const int M=2e6+10;
const int inf=2e7;
int phi[N],m,prime[M];bool v[N];
ll f[N];
inline void g_p()
{
    m=0;
    for(int i=2;i<=N;i++)
    {
        if(!v[i]){phi[i]=i-1;prime[++m]=i;}
        for(int j=1;j<=m&&i*prime[j]<=inf;j++)
        {
            v[i*prime[j]]=1;
            if(!(i%prime[j]))
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            else phi[i*prime[j]]=phi[i]*(prime[j]-1);
        }
    }
}
int main()
{
    g_p();f[2]=1;
    for(int i=3;i<=N;i++)f[i]=f[i-1]+phi[i];
    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x;scanf("%d",&x);
        printf("%lld\n",f[x]);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值