BZOJ2005:[Noi2010]エネルギーハーベスティング(オイラー関数)

説明

別の後、土地の長方形の部分があり、彼は地面にエネルギープラントを植え、この植物は太陽光のエネルギーを取り込むことができます。エネルギープラント、収穫後
と多くのエネルギープールを、その後収集エネルギーがプールされた植物のマシンを使用しています。別の非常にニートの植物種、n列の合計後、各列は、
別の後の各つの植物の座標(X、Y)はここで、x、表現されることができるために、m個の木、植物、垂直ピッチは、同じである含みますnの範囲1において、
Xの列を示し、Yは、X-Yツリーの最初の列に示される、1からmまでの範囲です。、大きな少ないポータブル、およびそれの多くのエネルギー収集機が配置されますので
、コーナーに、ちょうど(0、0)座標れます。エネルギー収集機は、コレクションの過程で一定のエネルギー損失を持っています。マシンとエネルギープラントであれば一緒に
K-植物ツリーを一緒に結ぶ線分と、エネルギー損失が2K + 1です。例えば、エネルギーは、収集機械座標によって収集された場合(2、4)植物の、以降の
接続線(1、2)、3は、エネルギーロスを生成するために植物の存在。なお、植物は、線分上に接続されたエネルギー回収装置の植物ではない場合
、そのエネルギー損失1。今、総エネルギーロスを計算します。ここで、エネルギーハーベスティング、N = 5、M = 4の例であり、20人の総
エネルギー回収機は各植物にそのエネルギーを収集する際のエネルギーの損失を示すケ所が発生します。この例では、36のエネルギーの総生成
量の損失を。

入力

これは、2つの整数nとmの行が含まれています。

出力

のみ発生するエネルギーの全損失を表す整数を含んでいます。

サンプル入力

サンプル入力[1]

5 4

サンプル入力[2]

3 4

サンプル出力
[1]サンプル出力

36

出力例[2]

20

1≤N、Mの≤:100,000データの100%まで。

点(i、j)の損失である\(2 * GCD(I、J)-1 \)、n型領域のすべての行m列の全損失である:
\ [\ sum_ 1} ^ {N = \ sum_ {J}。1 ^ M =(2 * GCD(I、J)-1)\]
\ [= 2 \ sum_。1} ^ {N-I = \ sum_ {J} = ^ MGCD。1(I、J) -nm \]
私たちが解決する必要があることを意味し、N-(\ sum_ {J = 1} ^ MGCD(I、J)は、\ \ sum_ {i = 1} ^)\を、あなたはこの問題を解決することができます。

多くの要因のオイラー関数のすべてのため、この数に等しいです。
\ [\ Sum_ {D | N
} \ PHI(D)= N \] に変換することができる
\ [\ sum_ {i = 1 } ^ n個の\ sum_ {J = 1} ^ m個の\ sum_ {D = 1} ^ { 分(i、j)は} [ D | I 及びd | J] \ PHI(D
)\] 交換順序で使用可能
\ [\ sum_ {D = 1 } ^ {分(N、M)} \ sum_ { I = 1} ^ N [D
| I] \ sum_ {J = 1} ^ M [D | J] * \ PHI(D)\] 以来\(\ sum_ {i = 1 } ^ ND | I = N / D \) \(1 \)\(N- \) Dには割り切れ有することができる\(N / D \)式はと等しくなるようにAを、
[\ sum_ {D = 1 \ } ^ {分(nは、 M)}(N / D)
*(M / D)* \ PHI(D)\] 我々は、前処理必要\(1E5 \)内にオイラー関数。
コード

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+10;
ll phi[N];
void init(int n)
{
    for(int i=1;i<=n;i++)
    {
        phi[i]=i;
    }
    for(int i=2;i<=n;i++)
    {
        if(phi[i]==i)
        {
            for(int j=i;j<=n;j+=i)
            {
                phi[j]=phi[j]/i*(i-1);
            }
        }
    }
}
int main()
{
    ll n,m;
    ll ans=0;
    cin>>n>>m;
    init(1e5);
    for(ll d=1;d<=min(n,m);d++)
    {
        ans+=(n/d)*(m/d)*phi[d];
    }
    ans=ans*2;
    ans-=n*m;
    cout<<ans<<"\n";
    return 0;
}

おすすめ

転載: www.cnblogs.com/hh13579/p/11790116.html