杜教筛样例过不了求助
  • 板块P2568 GCD
  • 楼主damuzhi
  • 当前回复3
  • 已保存回复3
  • 发布时间2024/6/7 10:09
  • 上次更新2024/6/7 15:36:08
查看原帖
杜教筛样例过不了求助
1127424
damuzhi楼主2024/6/7 10:09
#include <bits/stdc++.h>

using namespace std;

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

long long asd = 0;

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

void init()
{
    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;
            }
            for(int j = 0; j < cnt && i * prime[j] <= N; j++)
            {
                vis[i * prime[j]] = 1;
                if(i % prime[j])
                {
                    phi[i * prime[j]] = phi[i] * phi[prime[j]];
                }
                else
                {
                    phi[i * prime[j]] = phi[i] * prime[j];
                    break;
                }
            }
        }
        for(int i = 1;i <= N; i++)
        {
            phi[i] += phi[i - 1];
        }
    
}

int gsum(int x)
{
    return x;
}

ll getsphi(int 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()
{
    init();
    int n;
    cin >> n;
    for(int i = 1; i < cnt; i++)
    asd += 2*getsphi(n/prime[i])-1;
    cout << asd << endl;
    return 0;
}
2024/6/7 10:09
加载中...