zoukankan      html  css  js  c++  java
  • AcWing 220. 最大公约数 | 欧拉函数

    传送门

    题目描述

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

    GCD(x,y)即求x,y的最大公约数。

    输入格式

    输入一个整数N

    输出格式

    输出一个整数,表示满足条件的数对数量。

    数据范围

    1≤N≤10^7

    输入样例:

    4
    

    输出样例:

    4

    题解:本题要求1<=x,y<=N且GCD(x,y)为素数的数对(x,y)数量,相当于求:对于N以内的每一个素数p,1<=x,y<=N/p 中GCD(x,y)为1的数对(x,y)数量和。我们知道欧拉函数的定义是1~n中与n互质的数的个数,那么对于p,1<=x,y<=N/p 中GCD(x,y)为1的数对(x,y)数量为φ(1)+φ(2)...+φ(N/p),可以用前缀和计算。要注意:x,y大小关系无影响所以要*2,但x,y相同时只算一次所以要-1。题目就变成了求[sum_{p是素数}^{p≤n} 2*sum_{i=1}^{n/p}φ(i) -1]  也可以用[sum_{p是素数}^{p≤n} 2*sum_{i=2}^{n/p}φ(i) +1]。

        

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int N = 1e7 + 10;
    int v[N],prime[N];
    ll sum[N],phi[N];
    int cnt = 0;
    int main() {
        int n;
        scanf("%d",&n);
        phi[1]=1;
        for (int i = 2; i <= n; i++) {
            if(!v[i]) {
                v[i] = i;prime[cnt++] = i;
                phi[i] = i-1;
            }
            for (int j = 0; j < cnt; j++) {
                if (prime[j] > v[i] || prime[j] > n/i) break;
                v[i*prime[j]] = prime[j];
                phi[i*prime[j]] = phi[i] * (i%prime[j]?prime[j]-1:prime[j]);
            }
        }
        for (int i = 1; i <= n; i++) 
            sum[i] = sum[i-1]+phi[i];
        ll ans = 0;
        for (int i = 0; i < cnt; i++) {
            int num = n/prime[i];
            ans += 2*sum[num]-1;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    [Leetcode] Largest Rectangle in Histogram
    [Leetcode] Unique Binary Search Trees II
    [Leetcode] Remove Duplicates from Sorted List II
    [Leetcode] Container With Most Water
    [Leetcode] Trapping Rain Water
    [Jobdu] 题目1390:矩形覆盖
    [Leetcode] Integer to Roman
    [Leetcode] Word Break
    Notes on Convolutional Neural Networks
    lecture5-对象识别与卷积神经网络
  • 原文地址:https://www.cnblogs.com/l999q/p/11367956.html
Copyright © 2011-2022 走看看