GCD - Extreme (II) (Euler function)

B [n] represents 1 to n-1 and n and gcd so dp [n] = dp [n-1] + dp [n];

a [i] represents the number of x gcd (n, x) = i a;

Therefore, b [n] = sum (a [i] * i), we only need a [i] can;

The gcd (n, x) = i ---> gcd (n / i, x / i) = 1,

Thus only required Euler function phi (n / i), can be obtained with the n / i prime number;

Thereby obtaining gcd (x, n) = number i, so that the whole can be solved;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<bitset>

#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define sd(x) scanf("%d",&(x))
#define sl(x) scanf("%lld",&(x))
#define slf(x) scanf("%lf",&(x))
#define scs(s) scanf("%s",s)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define lowbit(x) x&(-x)
#define ls now<<1
#define rs now<<1|1
#define lson l,mid,ls
#define rson mid+1,r,rs
#define int long long

using namespace std;

const int maxn=5e6+10;
const int N=4000001;

int a[maxn],b[maxn],dp[maxn];

void oula()
{
    //a[1]=1;
    for(int i=2;i<N;i++)
    {
        if(!a[i])
        {
            for(int j=i;j<N;j+=i)
            {
                if(!a[j]) a[j]=j;
                a[j]=a[j]/i*(i-1);
            }
        }
    }
}

#undef int
int main()
{
#define int long long
    oula();

    for(int i=1;i<N;i++)
        for(int j=i*2;j<N;j+=i)
            b[j]+=a[j/i]*i;

    for(int i=2;i<N;i++)
        dp[i]=dp[i-1]+b[i];

    int n;
    while(~sl(n)&&n)
        printf("%lld\n",dp[n]);

    return 0;
}

 

Guess you like

Origin www.cnblogs.com/minun/p/11348521.html