UVA11426 GCD - Extreme (II) 究极GCD 欧拉函数

  • 题目链接

  • 题意
    输入正整数n,求 gcd(1,2)+gcd(1,3)+gcd(2,3)+...+gcd(n1,n), g c d ( 1 , 2 ) + g c d ( 1 , 3 ) + g c d ( 2 , 3 ) + . . . + g c d ( n − 1 , n ) , 即求所有满足 1i<jn 1 ≤ i < j ≤ n 的数对 (i,j) ( i , j ) 所对应的 gcd(i,j) g c d ( i , j ) 之和。

  • 分析

    f(n)=gcd(1,n)+gcd(2,n)+gcd(3,n)+...+gcd(n1,n), f ( n ) = g c d ( 1 , n ) + g c d ( 2 , n ) + g c d ( 3 , n ) + . . . + g c d ( n − 1 , n ) , 则答案为 S(n)=f(2)+f(3)+...+f(n),S(n)=S(n1)+f(n) S ( n ) = f ( 2 ) + f ( 3 ) + . . . + f ( n ) , 则 S ( n ) = S ( n − 1 ) + f ( n )
    g(n,i) g ( n , i ) 表示满足 gcd(x,n)=ix<n g c d ( x , n ) = i 且 x < n 的正整数 x x 的个数,则f(n)=sum{ig(n,i)|in}
    若依次计算 f(n) f ( n ) ,速度较慢,但可以逆向思维,对每个 i i 枚举它的倍数n(并更新 f(n) f ( n ) 的值),时间复杂度与素数筛法一样。

  • 代码

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn=4e6+2;
ll s[maxn],f[maxn];
int n;
int p[maxn+10]={0};
void init()
{
    int i,j;
    for(i=1; i<=maxn; i++)  p[i]=i;
    for(i=2; i<=maxn; i+=2) p[i]/=2;
    for(i=3; i<=maxn; i+=2)
        if(p[i]==i){
            for(j=i; j<=maxn; j+=i)
                p[j]=p[j]/i*(i-1);
        }
}

int main()
{
    init();
    memset(f,0,sizeof(f));
    for(int i=1;i<=maxn;++i)
        for(int n=i+i;n<=maxn;n+=i)
            f[n]+=i*p[n/i];
    s[2]=f[2];
    for(int i=3;i<=maxn;++i)
        s[i]=s[i-1]+f[i];
    while(scanf("%d",&n),n)
        printf("%lld\n",s[n]);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值