羅区P5221製品オイラーの定理オイラー機能+

羅区P5221 製品

タグ

  • オイラー機能
  • オイラーの定理

序文

  • ノー

質問の簡潔な意味

  • 求:
    \ [\ prod_ {i = 1} ^ N \ prod_ {jは= 1} ^ n個の\ FRAC {LCM(I、J)} {GCD(I、J)}(\%104857601)\]
  • データ範囲は1E6で、時間は0.2秒です

考え

  • 元の式\(LCM \)\(GCD \)を表し、従って元の式:
    \ [\ prod_ 1} ^ {N-I = \ J = prod_ 1} ^ {N- \ IJ FRAC {が} {\左( GCD(i、j)は\右 )^ 2} \]

    一般的に、\(LCMは\)されていない(GCDを\)\明らか再帰として、そう\(LCM \)直接決定しない、通常だろう\(\ LCM)に変換される\(GCD \)シークします\(LCM \) および\(GCD(I、J)* LCM(I、J)= \のIJ) そう\(LCM(I、J) = \ FRAC {IJ} {GCD(I、J)} \)

  • オープン連想を使用して:
    \ [\ prod_ 1} ^ {N-I = \ {prod_ J = NIJ 1} ^ * \左(\ prod_ 1} ^ {N-I = \ prod_ 1} = {J ^ ngcd(I。 、J)\右)^ { - 2} \]

    乗算/累算式がこのような特性:(結合性を満たす)
    \ [\ sum_ {I}(a_iを+ B_i)= \ sum_ia_i + \ sum_ib_i \]
    \ [\ prod_ {I}(a_iを+ B_i)= \ prod_ia_i * \ prod_ib_i \]

    複数のスタイルになお、:に\(\ \合計)を持っている
    \ [\合計\ limits_ia_i \合計
    \ limits_jb_j = \合計\ limits_ia_i * \合計\ limits_jb_j \] で\(\のprod \)
    \ [\ PROD \ limits_ia_i \ PROD \ limits_j ^
    nb_j = \ PROD \ limits_ia_i * \ ^ N \](\ PROD \ limits_jb_j \右)左したがって、合計シンボル数、を乗じた場合(\ \ SUM \)の乗算ではすることができ省略\(\のprod \)で乗算記号を省略しないように覚えています

    トピック:割当率:
    \ [\ sum_ika_i = K \ sum_ia_i \]
    \ [\ prod_i nka_i ^ = N-K * ^ \ ^ N-prod_i a_iを、および\]

    分配率は数に\乗り型が先行言及されるべきです

  • 先求\(\ PRODの\のlimits_ {i = 1} ^ N \ PROD \ limits_ {J = 1} ^ NIJ \)直接分配律得:
    \ [\ PRODの\のlimits_ {I = 1} ^ nは左、\を( prod \のlimits_ \私は^ n個の* \ prodにするの\ limits_ {J = 1} ^ NJ \右)= {I = 1} ^ n個のn(\右!左(I ^ n個の* nを\)=!)^ n個* (N!)\ prod_ {i = 1} ^ NI ^ N =(N!)^ n個の* ^ N =(N!)^ {2N} \]
  • 最初の式はこのように解決するために、我々は今、第2の式を求める。。。\(\のprod \ limits_ 1} ^ {N-I = \のProd \ limits_ 1} = {J ^ ngcd(I、J)\ )、列挙最初\(GCDを\)出現回数で電力値にその後、:
    \ [\ prod_ 1 = {X} ^ {^ NX \ sum_ 1} ^ {N-I = \ sum_ { J = 1} ^ N [GCD (I、J)== X]} \]
  • 後ろ\(\和\ limits_ {I = 1} ^ n個の\和\ limits_ {J = 1} ^ N [GCD(I、J)== X] \)は慣れていないのですか?彼は同等です\(2pre \ファイ([\ FRAC NX]) - 1 \)ここでは学生に紹介(オイラー関数は、私の2倍に明らかではない。のオイラー機能について話した記事の記事の分類の下で)、これに等しい第2の式:
    \ [^ \ prod_ 1 = {X} {。)] ^ NX 2pre \ピー([\ NXのFRAC - 1} \]
  • したがって、合計式は、必要とされる:
    \ [(!N-)} ^ {2N * \左(\ prod_ 1 = {X} ^ {^ NX 2pre \ピー([\ NXのFRAC]) - 1} \右)^ {-2} \]
  • 式急速パワーの左側\は(O(nlogn)\) 画面の右それに対処できるようになり、その後、線形プレフィックスを進めるとアウトすることができ( - 1 \ 2pre \ピー([\ FRAC NX]))\、探し出します逆数を与えるために右の式を見つけ、我々は答えを見つけることができるようになります。
  • なお、ここで\(X \)インデックスがモジュロされていないため、Googleのインデックスの一部は、配列を保存されていますが、むしろモジュロより真値である必要があります値を保存することです!混同してはいけません。
  • だから、指標の実際の値がint型以上で、我々は唯一の専用メモリの7.8メガバイトの対象インデックスの保存LONGLONG、int型= 250について1キロバイトを開くことができ、手の数が、オープンLONGLONG劣らを見つけません。したがって、我々はまた、インデックスに金型を取る必要があります。どのように剰余?オイラーの定理、限り弾性率は、金型内の電力計算を意味素数、であるとして、あなたはモジュラス-1であるオイラー関数の係数に%番目に進むことができ、その後、ACのことができるようになります。

注意事項

概要

  • 一般的に、\(LCMは\)されていない(GCDを\)\明らか再帰として、そう\(LCM \)直接決定しない、通常だろう\(\ LCM)に変換される\(GCD \)シークします\(LCM \) および\(GCD(I、J)* LCM(I、J)= \のIJ) そう\(LCM(I、J) = \ FRAC {IJ} {GCD(I、J)} \)
  • 法律のオペレータの概要:

    乗算/累算式がこのような特性:(結合性を満たす)
    \ [\ sum_ {I}(a_iを+ B_i)= \ sum_ia_i + \ sum_ib_i \]
    \ [\ prod_ {I}(a_iを+ B_i)= \ prod_ia_i * \ prod_ib_i \]

    複数のスタイルになお、:に\(\ \合計)を持っている
    \ [\合計\ limits_ia_i \合計
    \ limits_jb_j = \合計\ limits_ia_i * \合計\ limits_jb_j \] で\(\のprod \)
    \ [\ PROD \ limits_ia_i \ PROD \ limits_j ^
    nb_j = \ PROD \ limits_ia_i * \ ^ N \](\ PROD \ limits_jb_j \右)左したがって、合計シンボル数、を乗じた場合(\ \ SUM \)の乗算ではすることができ省略\(\のprod \)で乗算記号を省略しないように覚えています

    トピック:割当率:
    \ [\ sum_ika_i = K \ sum_ia_i \]
    \ [\ prod_i nka_i ^ = N-K * ^ \ ^ N-prod_i a_iを、および\]

    分配率は数に\乗り型が先行言及されるべきです

  • 以下のための逆元演算ことに注意してください\(\ FRAC AB&\ INVの%P = A *(B用の\%のP)\%P \) 逆数はモジュロ予め計算さ!
  • \(^ AのBの\%pが\) 操作を進めることができモッズPが、モジュロP bは、事前に全く受け入れられないが、オイラーの定理を使用する必要があります。

ACコード

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn = 1e6 + 10;
const int mod = 104857601;

bool no_prime[maxn];
int prime[maxn], phi[maxn];
int shai(int n)
{
    int cnt = 0;
    phi[1] = 1;

    for (int i = 2; i <= n; i++)
    {
        if (!no_prime[i])
            prime[++cnt] = i, phi[i] = i - 1;

        for (int j = 1; j <= cnt && prime[j] * i <= n; j++)
        {
            no_prime[prime[j] * i] = 1;
            phi[prime[j] * i] = i % prime[j] == 0 ? phi[i] * prime[j] : phi[i] * (prime[j] - 1);
            if (i % prime[j] == 0) break;
        }
    }

    for (int i = 1; i <= n; i++)
        phi[i] = (phi[i - 1] + 2 * phi[i]) % (mod - 1);

    return cnt;
}

int ksm(int a, int b)
{
    int ans = 1, base = a;
    while (b)
    {
        if (b & 1)
            ans = 1ll * ans * base % mod;
        base = 1ll * base * base % mod;
        b >>= 1;
    }
    return ans;
}

void solve()
{
    int n;
    scanf("%d", &n);
    shai(n);

    int ans = 1;
    for (int i = 1; i <= n; i++)
        ans = 1ll * ans * i % mod;
    ans = ksm(ans, 2 * n);

    int tot = 1;
    for (int x = 1; x <= n; x++)
        tot = (1ll * tot * ksm(x, phi[n / x] - 1)) % mod;

    printf("%d", 1ll * ans * ksm(1ll * tot * tot % mod, mod - 2) % mod);
}

int main()
{
    solve();
    return 0;
}

おすすめ

転載: www.cnblogs.com/danzh/p/11309179.html