码迷,mamicode.com
首页 > 其他好文 > 详细

luogu P2568 GCD

时间:2018-12-15 12:01:45      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:spl   const   code   void   put   prime   break   oid   getc   

luogu P2568 GCD

\[\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)==p]\]

完全可以套用YY的GCD方法来做.这里有一个十分好用的思想与方法.
\[\sum_{p}\sum_{i=1}^{\frac np}\sum_{j=1}^{\frac mp}[gcd(i,j)==1]\]
\[\sum_{p}\sum_{i=1}^{\frac np}\phi(i) * 2 - 1\]
只要筛出函数\(phi(i)\)
那么就可以在\(O(\pi (n))\)的时间内求得

#include <iostream>
#include <cstdio>
#define rep(i , x, p) for(register int i = x;i <= p;++ i)
#define gc getchar()
#define pc putchar
#define ll long long
const int maxN = 1e7 + 7;

int num , prime[maxN], phi[maxN];
bool is_prime[maxN];
ll sum[maxN];

inline void init(int n) {
    phi[1] = 1;
    rep(i , 2, n) {
        if(!is_prime[i]) prime[++ num] = i , phi[i] = i - 1;
        for(register int j = 1;j <= num && i * prime[j] <= n;++ j) {
            is_prime[i * prime[j]] = true;
            if(i % prime[j] == 0) {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
            phi[i * prime[j]] = phi[i] * ( prime[j] - 1 );
        }
    }
    rep(i , 1, n) sum[i] = sum[i - 1] + phi[i];
}

int main() {
    int n;
    scanf("%d",&n);
    init(n);
    long long ans = 0;
    rep(i , 1, num) ans += sum[n / prime[i]] * 2 - 1;
    printf("%lld",ans);
    return 0;
}

luogu P2568 GCD

标签:spl   const   code   void   put   prime   break   oid   getc   

原文地址:https://www.cnblogs.com/gzygzy/p/10122519.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!