[NOI2010] 能量採集 (數學)

[NOI2010] 能量採集

題目描述

棟棟有一塊長方形的地,他在地上種了一種能量植物,這種植物能夠採集太陽光的能量。在這些植物採集能量後,棟棟再使用一個能量聚集機器把這些植物採集到的能量聚集到一塊兒。c++

棟棟的植物種得很是整齊,一共有n列,每列有m棵,植物的橫豎間距都同樣,所以對於每一棵植物,棟棟能夠用一個座標(x, y)來表示,其中x的範圍是1至n,表示是在第x列,y的範圍是1至m,表示是在第x列的第y棵。spa

因爲能量聚集機器較大,不便移動,棟棟將它放在了一個角上,座標正好是(0, 0)。code

能量聚集機器在聚集的過程當中有必定的能量損失。若是一棵植物與能量聚集機器鏈接而成的線段上有k棵植物,則能 量的損失爲2k + 1。例如,當能量聚集機器收集座標爲(2, 4)的植物時,因爲鏈接線段上存在一棵植物(1, 2),會產生3的能量損失。注意,若是一棵植物與能量聚集機器鏈接的線段上沒有植物,則能量損失爲1。如今要計算總的能量損失。blog

下面給出了一個能量採集的例子,其中n = 5,m = 4,一共有20棵植物,在每棵植物上標明瞭能量聚集機器收集它的能量時產生的能量損失。ci

在這個例子中,總共產生了36的能量損失。it

輸入輸出格式

輸入格式:io

僅包含一行,爲兩個整數n和m。class

輸出格式:gc

僅包含一個整數,表示總共產生的能量損失。im

輸入輸出樣例

輸入樣例#1:

5 4

輸出樣例#1:

36

輸入樣例#2:

3 4

輸出樣例#2:

20

說明

對於10%的數據:1 ≤ n, m ≤ 10;
對於50%的數據:1 ≤ n, m ≤ 100;
對於80%的數據:1 ≤ n, m ≤ 1000;
對於90%的數據:1 ≤ n, m ≤ 10,000;
對於100%的數據:1 ≤ n, m ≤ 100,000。

Solution

對於題意,大體就是求這個
\[\sum_{i=1}^{n}\sum_{j=1}^{m}gcd(i,j)\times 2-1\]
\(gcd(i,j)\)表示(0,0)到(i,j)直線上點的個數+1

其實就是對於一個公約數x,方案數就是\((x\times 2-1)\times(\)\(x\)\(gcd\)的數對的個數\()\)

咱們令\(f[x]\)表示後一個括號中的意思,顯然\(f[x]=(n/x)\times (m/x)-\sum_{i=2}^{min(n,m)/d}\times d\)的倍數
那麼倒序枚舉就能夠了

Code

#include<bits/stdc++.h>
#define rg register
#define lol long long
using namespace std;
const int N=1e5+10;
lol ans,n,m,f[N];
int main()
{
    cin>>n>>m;
    if(n>m) swap(n,m);
    for (rg int i=n;i>=1;i--) {
        f[i]=(n/i)*(m/i);
        for (rg int j=i<<1;j<=n;j+=i) f[i]-=f[j];
        ans+=((i<<1)-1)*f[i];
    }cout<<ans<<endl;
}
相關文章
相關標籤/搜索