70pts杜教筛,wa了,#2#4#9(重构码风)
  • 板块P2568 GCD
  • 楼主damuzhi
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/6/7 21:15
  • 上次更新2024/6/7 21:48:23
查看原帖
70pts杜教筛,wa了,#2#4#9(重构码风)
1127424
damuzhi楼主2024/6/7 21:15
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const ll N = 1e7+7;
ll prime[N];
bool vis[N];
ll  mu[N];
ll phi[N];

ll anss;

ll cnt = 0;
unordered_map<int,ll> summu;
unordered_map<int,ll> sumphi;

void init(ll n)
{
    vis[0] = vis[1] = 1;//0,1不是质数
    mu[1] = phi[1] = 1;
    for(int i = 2; i < n; i++)
    {
            if(!vis[i])
            {
                prime[cnt++] = i;
                phi[i] = i-1;
                mu[i] = -1;
            }
            for(int j = 0; j < cnt && i * prime[j] <= n; j++)
            {
                vis[i * prime[j]] = 1;
                if(i % prime[j])
                {
                    mu[i * prime[j]] = -mu[i];
                    phi[i * prime[j]] = phi[i] * phi[prime[j]];
                }
                else
                {
                    mu[i * prime[j]] = 0;
                    phi[i * prime[j]] = phi[i] * prime[j];
                    break;
                }
            }
        }
        for(int i = 1;i <= n; i++)
        {
            mu[i] += mu[i - 1];
            phi[i] += phi[i - 1];
        }
    
}

int gsum(ll x)
{
    return x;
}

ll getsphi(ll x)
{
    if(x < N) return phi[x];
    if(sumphi[x]) return sumphi[x];
    ll ans = x * ((ll)x+1) / 2;
    for(ll l = 2,r; l <= x; l = r+1)
    {
        r = x/(x/l);
        ans -= (gsum(r) - gsum(l - 1)) * getsphi(x/l);
    }
    return sumphi[x] = ans/gsum(1);//既然构造了一个多余的函数,就要把他还原
}

int main()
{
    ll n;
    cin >> n;
    init(n);
    for(ll i=0;i<cnt;i++) anss+=2*getsphi(n/prime[i]);
    anss -= cnt;
    cout << anss << endl;
    return 0;
}
2024/6/7 21:15
加载中...