LJJカウント愛(メビウス反転)

質問の意味:

所与の(N- \)\満足しようと、\(\ FRAC {1} {A} + \ FRAC {1} {B} = \ FRAC {1} {C}を\)、及び(A、B、Cを\ \ )互いに素トライアド\((A、B、C )\) 数。\((A、B、C \ N-1当量)\)
\(N- \ leq10 12である^ {} \)

同様まず、P5253ディオファントス方法、両側を乗算する(\ ABC \)

\(AC + BC = AB \)
\(AB-AC-BC + C ^ 2 = C ^ 2 \)
\((AC)(BC)= C ^ 2 \)

セット\(AC = X \)、\ (BC = Y \) 次いで\(XY = C ^ 2 \
) であれば\(A、B、C \ ) 、次いで、素数があるれていない\(G、(G> 1)\)を満足\(G |(X + C )\) と\(G |(Y + C )\) と\(G | C \)
そう\(G | X \)\(G | Y \)\(G | C \) 満たされた(X、Y、C \ \ ) と互いに素

場合は(X、Y、C \ \ ) 素数ではない、そこである(G、(G> 1 \ )\) を満足\(X = GX '\)\(Y = GY' \)\(G | C \) 。
その\(x'y'g = C ^ 2 ^ 2 \)、\ (G ^ 2 | C ^ 2 \)、\ (G | C \)
すなわち限り、あるとして\(G | X \)\(G | Y- \) 適合することができるであろう\(G | C \)

したがって、限り\(GCD(X、Y) = 1 \) することができます。
また、満たすために\(MAX(X、Y)+ C \ N-のLeq \)を
我々は仮定することができる(Y <X \)\次に、\(X + C \ N-のLeq \)

ので\(GCD(X、Y)= 1 \)ので、\(C ^ 2 \)生殖質因子あたりは、いずれかのXを与え、またはyを与えました。
したがって、\(X、Y、\は)完璧な正方形です。

セット\(I ^ 2 = X \)、\ (J ^ 2 = Y(J <I)\) 次いで\(C = ijの\)
以降\(I ^ 2 + ijの\ n型のLeq \) そう\(I(I + J)\ N-のLeq \) すなわち\(J \のLeq \ {N-FRAC} {I} -i \)

セット\(R_iを=分(1-I、\ {N-FRACの-i} {I})\)、答えは
\(\ sum_ {iは1 = } ^ N {\ sum_ {J = 1} ^ {R_iを} [GCD(I、J)
= 1]} \) 直接メビウス反転:
\(\ sum_ {D} = ^ NU 1(D){\ sum_ {D | I {}} ^ {\左\ lfloor \ FRAC {R_iを} { D} \右\ rfloor}} \)

場合\(I> \ SQRT {N } \) 、見かけの\(R_iを= 0 \)を無視することができます。

時間複雑\(O(\ログ} N-SQRT {\ N-SQRT {})\)
最後に、2を取ることを忘れないでください。

コード:

#include <stdio.h>
#define ll long long
ll R[1000010];
int sa[1000010],ss[1000010],u[1000010],sl=0;
void getu(int n)
{
    u[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!sa[i])
        {
            ss[sl++]=i;
            u[i]=-1;
        }
        for(int j=0;j<sl&&i*ss[j]<=n;j++)
        {
            sa[i*ss[j]]=true;
            if(i%ss[j]==0)
            {
                u[i*ss[j]]=0;
                break;
            }
            u[i*ss[j]]=-u[i];
        }
    }
}
int main()
{
    ll n,ans=0;int m=0;
    scanf("%lld",&n);
    if(n==1)
    {
        printf("0");
        return 0;
    }
    for(int i=2;i<=n;i++)
    {
        R[i]=n/i-i;
        if(i-1<R[i])
            R[i]=i-1;
        if(R[i]<=0)
            break;
        m=i;
    }
    getu(m);
    for(int i=1;i<=m;i++)
    {
        if(u[i])
        {
            for(int j=i;j<=m;j+=i)
                ans+=u[i]*(R[j]/i);
        }
    }
    printf("%lld",ans*2+1);
    return 0;
}

おすすめ

転載: www.cnblogs.com/lnzwz/p/12128600.html