欧拉函数(欧拉函数是求小于 x 并且和 x互质 的数的个数)

φ(N)=N(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn) //注意这里的n
φ(1)=1
1.欧拉函数是积性函数——若 m,n 互质,φ(mn)=φ(m)φ(n)
2.若 n 是素数 p 的 k 次幂,φ(n)=pk-p(k-1)=(p-1)p^(k-1),也就是在p的基础上乘上(p-1)
因为除了 p 的倍数外,其他数都跟 n 互质
3.pj是i的最小质因子 phi[ipj]=phi[i]pj
4.0和1互质 在一些范围内满足一些欧拉函数点对的性质即phi[1]=1 但是0和1不是质数

void get_eulers(int n)
{
    phi[1] = 1;//****
    for (int i = 2; i <= n; i++)
    {
        if (!st[i])
        {
            primes[cnt++] = i;
            phi[i] = i - 1; //****
//对于质数i 1~i-1都与他互质
        }

        for (int j = 0; primes[j] <= n / i; j++)
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0)
            {
                phi[primes[j] * i] = phi[i] * primes[j]; 
                break;
            }
            phi[primes[j] * i] = phi[i] * (primes[j] - 1);
//pj不是i的最小质因子 所以要将pj*i比i多了一个质数pj 所以由欧拉函数 需要多算一个(1-1/pj)
//如果i和p互质 那么 phi[i*p]=phi[i]*phi[p]
        }
    }

可见的点https://www.acwing.com/problem/content/203/#

0≤x,y≤N 所以有phi[1]
能照射到的点是 y=kx直线的第一个点 k=y0/x0 就是说y0/x0是一个互质
所以就是0-n多少个数对满足x y互质
看y=x下面 x=1 x=2 x=3求互质的点的个数
gcd(1,1)答案是1

#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010;

int primes[N], cnt;
bool st[N];
int phi[N];

void init(int n)
{
    phi[1] = 1;
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i])
        {
            primes[cnt ++ ] = i;
            phi[i] = i - 1;
        }
        for (int j = 0; primes[j] * i <= n; j ++ )
        {
            st[i * primes[j]] = true;
            if (i % primes[j] == 0)
            {
                phi[i * primes[j]] = phi[i] * primes[j];
                break;
            }
            phi[i * primes[j]] = phi[i] * (primes[j] - 1);
        }
    }
}

int main()
{
    init(N - 1);

    int n, m;
    cin >> m;
    for (int T = 1; T <= m; T ++ )
    {
        cin >> n;
        int res = 1;//(1,1)点
        for (int i = 1; i <= n; i ++ ) res += phi[i] * 2;
        cout << T << ' ' << n << ' ' << res << endl;
    }

    return 0;
}

求满足条件 x y gcd(x,y)为素数的数对多少个#

https://www.acwing.com/problem/content/222/
(x,y)=p
(x/p,y/p)=1
等价于求 1<=x y<=N/p (缩小了范围) 所以没有phi[1]
所以就是求范围内(x/p,y/p)=1的个数

#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 1e7 + 10;

int primes[N], cnt;
bool st[N];
int phi[N];
LL s[N];

void init(int n)
{
    //这里隐含着 phi[1]=0
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i])
        {
            primes[cnt ++ ] = i;
            phi[i] = i - 1;
        }
        for (int j = 0; primes[j] * i <= n; j ++ )
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0)
            {
                phi[i * primes[j]] = phi[i] * primes[j];
                break;
            }
            phi[i * primes[j]] = phi[i] * (primes[j] - 1);
        }
    }

    for (int i = 1; i <= n; i ++ ) s[i] = s[i - 1] + phi[i];
}

int main()
{
    int n;
    cin >> n;
    init(n);

    LL res = 0;
    for (int i = 0; i < cnt; i ++ )
    {
        int p = primes[i];
        res += s[n / p] * 2 + 1;
    }

    cout << res << endl;

    return 0;
}


posted @   liang302  阅读(529)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示
主题色彩