第九届蓝桥杯国赛(c/c++ B组)最后一题

时间:2022-09-10 14:14:56

题目:以后补上。。。

分析:枚举求出n以内gcd为x的对数,求n以内gcd为x的对数就是求n/x以内gcd为1的对数,所以只要预先用欧拉线性筛法求出n以内的数欧拉函数,做个前缀和就行了。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll N = 1e7+5;
const ll p = 1e9+7;
ll phi[N],s[N],cnt,vis[N],prim[N];

void init(){///欧拉线性筛模板 
    phi[1] = 1;
    for(int i=2;i<=N;i++){
        if(!vis[i]) {
            phi[i] = i-1;
            prim[++cnt] = i;
        }
        for(int j=1;j<=cnt;j++) {
            int tp = prim[j];
            if(i*tp>N) break;
            vis[i*tp]=true;
            if(i%tp==0) {
                phi[i*tp]=phi[i]*tp; break;
            }else phi[i*tp]=phi[i]*phi[tp];
        }
    }
    s[1]=phi[1];
    for(int i=2;i<N;i++)
        s[i]=s[i-1]+2*phi[i];
}

int main(){
    int n;
    init();
    while(cin>>n) {
        ll ans=0;
        for(ll i=1;i<=n;i++)
            ans = (ans + s[n/i]*i%p*i%p)%p;
        cout<<ans<<endl;
    }
    return 0;
}