GCD --- 欧拉函数+质数筛选

传送门洛谷2568


题目描述

给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对.


分析

  题目所求为gcd(x, y) = p(p表示质数)的个数;对此,可以转化成:gcd(x/p, y/p) = 1;于是可以考虑欧拉函数,然后乱搞一下:
  对于 ϕ ϕ (x) 所属的数对(x, y), 它可以衍生出 若干(这里的组是指 (x, y), (y, x)),满足条件的数对 (x * p , y * p) {易知,每组所产生的数对是不同的}

  令k表示与i相乘后不大于n的质数个数, cnt表示n以内的质数个数
  则: ans = cnt + ni=2 ∑ i = 2 n ki ϕ(i) 2
  {由于未计算 (p, p) 的情况,所以加上cnt, 由于有(x, y)与(y,x) 两种,所以乘2}
  PS: ϕ(x) 为欧拉函数,表示在 [ [ 1 , x ) ) 中与x互质的个数

  举个例子: n = 10, ans = 30
  10以内的质数为2,3,5,7
  

iϕ(i)ki对答案的贡献213312=6322222=8421122=4541142=86200()

  故 ans=4()+6+8+4+8=30; a n s = 4 ( 质 数 个 数 ) + 6 + 8 + 4 + 8 = 30 ;
  ps:由上也可以推测k是递减的

  顺便讲讲欧拉函数的线筛求法(具体见代码):
  主要利用三个性质:
  若x为质数,则 ϕ(x)=x1 ϕ ( x ) = x − 1
  若 px p ∣ x p2x p 2 ∣ x ,则 ϕ(x)=ϕ(x/p)p ϕ ( x ) = ϕ ( x / p ) ∗ p
  若 px p ∣ x p2x p 2 ∤ x ,则 ϕ(x)=ϕ(x/p)(p1) ϕ ( x ) = ϕ ( x / p ) ∗ ( p − 1 )


代码

注意开long long

#include <cstdio>
#include <cstdlib>
#include <algorithm>

#define IL inline 

using namespace std;

IL int read()
{   
    int sum = 0;
    bool k = 1;
    char c = getchar();
    for(;'0' > c || c > '9'; c = getchar())
    if(c == '-') k = 0;
    for(;'0' <= c && c <= '9'; c = getchar())
        sum = sum * 10 + c - '0';
    return k ? sum : -sum;
}

bool is_prime[10000005];
int cnt;
int prime[664600];
int phi[10000005];

IL void get_prime(int n)
{   
    is_prime[1] = 1;
    phi[1] = 1;
    for(int i = 2, j; i <= n; ++i)
    {
        if(!is_prime[i]) { prime[++cnt] = i; phi[i] = i - 1;}
        for(j = 1; j <= cnt && (long long)i * prime[j] <= n; ++j)
        {
            is_prime[i * prime[j]] = 1;
            phi[i * prime[j]] = phi[i] * (i % prime[j] ? prime[j] - 1 : prime[j]);
            if(!(i % prime[j])) break;
        }
    }
}

int main()
{   
    int n = read();
    get_prime(n);

    long long ans = cnt;

    int r = cnt;
    for(int i = 2; i <= n; ++i)
    {
        for(;r && i * prime[r] > n; --r);
        if(!r) break;
        ans += phi[i] * r << 1;
    }
    printf("%lld", ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值