【未完善】GCD 极值(gcd) hgoi0501

GCD 极值(gcd) hgoi0501 题解


题目描述

题目描述


输入

  • 输入包括 T 组测试数据,每组数据只包含一个整数 N,含义如题所述。注意,测试数
    据中 T 的值未知。
    测试数据的最后一行是个 0,这一行无需处理。

输出

  • 每组测试数据输出一行,为 G 的值,其结果不会超过 64 位带符号整数。

样例

样例

数据规模

  • 对于 30% 的数据,2 N 1 000; 1 T 100
    对于 60% 的数据,2 N 4 000 000; 1 T 100
    对于另外的 40% 的数据,2 N 200 000; 1 T 20 000

题目解析

  • 一道非常玄妙的数学题。
  • 用到了欧拉函数的特性并使用递推和直接计算两种方法应对不同的数据规模。
  • 具体待补全

先附上AC程序

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
#define LIM 4000001
void finit(){
    freopen("gcd.in","r",stdin);
    freopen("gcd.out","w",stdout);
}
ll g[LIM],flag[LIM],phi[LIM],sumphi[LIM];
ll prime[300000];
int prf=0;

int main(){
    finit();
    for (int i=2;i<=LIM;i++){
        if (!flag[i]) prime[prf++]=flag[i]=i;
        for (int j=0;j<prf&&i*prime[j]<=LIM;j++){
            flag[i*prime[j]]=prime[j];
            if (i%prime[j]==0)
                break;
        }
    }
    phi[1]=1;
    for (int i=2;i<LIM;i++){
        phi[i]=phi[i/flag[i]];
        if ((i/flag[i])%flag[i]==0)
            phi[i]*=flag[i];
        else
            phi[i]*=(flag[i]-1);
        sumphi[i]=sumphi[i-1]+phi[i];
    }
    ll n;
    ll maxx=1,sum=0;
    while (cin>>n){
        if (!n) break;
        if (n<=200000){
            if (n>maxx){
                for (int i=maxx+1;i<=n;i++){
                    g[i]=g[i-1]+phi[i];
                    for (int j=2;j<=sqrt(i);j++)
                        if (i%j==0)
                            if (i/j!=j)
                                g[i]+=phi[i/j]*j+phi[j]*(i/j);
                            else
                                g[i]+=phi[i/j]*j;
                }
                maxx=n;
            }
            cout<<g[n]<<'\n';
        }else{
            sum=sumphi[n];
            for(int i=2;i<=n/2;i++){
                sum+=sumphi[n/i]*i;
            }
            cout<<sum<<'\n';
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值