プロジェクトオイラーの問題675

ORZ foreverlasting一緒に取得するには、このトピックのQQの前に長い時間のために彼に尋ねました(だから我々は長い間ギャルのために話をしました)

のは、どのような推測してみましょう\(S \)文字は、我々が使用ディリクレ畳み込みをプッシュします:

\ [\ | | \ムー2 ^ \オメガ=私はAST \します]

これは、それをよく理解されて、組み合わせにその意義を考えます

その後の両側で同じボリューム\(I \)は、次のとおりです。

\ [2 ^ \オメガ\ I = I AST \ AST I \ AST | \ムー| = D \ AST | \ムー| \]

その後まだ同じ、考える(| \ムーのD \のAST \ | \) 感覚の組み合わせ、正と負の場合は、実際にある\(D(N ^ 2) \)

従って我々は(I AST 2 ^ \オメガ\ = D(N-2 ^)\)\、すなわち\(S(N)= D (N ^ 2)\)

次いで明確(S \)を\乗法関数答えは階乗の形態である、からであることができる\(N-1 \)答えが押さ\(N- \)

複雑さは、おそらくあり、品質係数のすべての暴力的な分解を非常に暴力的なプロセスを考えてみましょう\(O(nは\ sqrtのN )\) の

それからちょうど少し良くコンピュータが必要です私は、CPUの香りをかいだているように見えます

そして、このプロセスを最適化する方法を検討し、我々は同様のルーチン、列挙する必要があるでしょうので、この方法が遅い理由を見つけたので、我々は唯一の各レコード番号を調べる必要があり、最低品質係数、各ダイレクトを削除し、あなたは、偶然に、カウントするように貢献することができます

この複雑さは、ああ、一緒に取得するには、失われた加藤といわ(\ \ログ)\、私は削除するために、少なくともダウンに加えて、その後も少なく、結局感じ\を(2 \)

その後、我々はすぐにこの質問を作ることができます(自分のノートパソコンを使用して走った2sが出てきました)

#include<cstdio>
#define RI register int
#define CI const int&
using namespace std;
const int N=10000000,mod=1000000087;
int prime[N+5],cnt,mnp[N+5],bkt[N+5],inv[(N<<1)+5],ret=1,ans;
#define Pi prime[j]
inline void init(void)
{
    RI i,j; for (mnp[1]=1,i=2;i<=N;++i)
    {
        if (!mnp[i]) mnp[i]=i,prime[++cnt]=i;
        for (j=1;j<=cnt&&1LL*i*Pi<=N;++j)
        {
            mnp[i*Pi]=Pi; if (i%Pi==0) break;
        }
    }
    for (inv[0]=inv[1]=1,i=2;i<=(N<<1)+1;++i)
    inv[i]=1LL*inv[mod%i]*(mod-mod/i)%mod;
}
#undef Pi
inline void inc(int& x,CI y)
{
    if ((x+=y)>=mod) x-=mod;
}
inline int sum(CI x,CI y)
{
    int t=x+y; return t>=mod?t-mod:t;
}
int main()
{
    freopen("ans.txt","w",stdout);
    init(); for (RI i=2;i<=N;++i)
    {
        ret=1LL*ret*inv[bkt[i]+1]%mod; inc(bkt[i],2); ret=1LL*ret*(bkt[i]+1)%mod;
        for (int x=i;x!=mnp[x];x/=mnp[x])
        {
            if (x/mnp[x]==mnp[x])
            {
                ret=1LL*ret*inv[bkt[x]+1]%mod*inv[bkt[mnp[x]]+1]%mod;
                inc(bkt[mnp[x]],sum(bkt[x],bkt[x]));
                ret=1LL*ret*(bkt[mnp[x]]+1)%mod; bkt[x]=0;
            } else
            {
                ret=1LL*ret*inv[bkt[x]+1]%mod*inv[bkt[mnp[x]]+1]%mod*inv[bkt[x/mnp[x]]+1]%mod;
                inc(bkt[mnp[x]],bkt[x]); inc(bkt[x/mnp[x]],bkt[x]);
                ret=1LL*ret*(bkt[mnp[x]]+1)%mod*(bkt[x/mnp[x]]+1)%mod; bkt[x]=0;
            }
        }
        inc(ans,ret);
    }
    return printf("%d",ans),0;
}

おすすめ

転載: www.cnblogs.com/cjjsb/p/11518890.html