P1447 [NOI2010]能量採集
一個植物 \((x,y)\) 與\((0,0)\)上的連線共有 \(gcd(x,y)\)個點,再減去兩個端點,
能量損失即為\(2\times(gcd(x,y)-2)+1 = 2\times gcd(x,y)+1\)
所以題目要求的即:
\(\sum\limits_{i=1}^n\sum\limits_{j=1}^m(2\times gcd(i,j)-1)\)
\(=2\times\sum\limits_{i=1}^n\sum\limits_{j=1}^mgcd(i,j) - n\times m\)
設\(f=\sum\limits_{i=1}^n\sum\limits_{j=1}^mgcd(i,j)\)
\(=\sum\limits_{d=1}^nd\sum\limits_{i=1}^n\sum\limits_{j=1}^m[gcd(i,j)=d]\)
\(=\sum\limits_{d=1}^nd\sum\limits_{i=1}^{\frac{n}{d}}\sum\limits_{j=1}^\frac{m}{d}\sum\limits_{k|i,k|j}\mu(k)\)
\(=\sum\limits_{d=1}^nd\sum\limits_{k=1}^\frac{n}{d}\mu(k)\dfrac{n}{kd}\times\dfrac{m}{kd}\)
設 \(T = kd\)
\(=\sum\limits_{T=1}^n\dfrac{n}{T}\times\dfrac{m}{T}\sum\limits_{k|T}\mu(k)\times\dfrac{T}{k}\)
根據\(id\times\mu=\varphi\)
\(=\sum\limits_{T=1}^n\dfrac{n}{T}\times\dfrac{m}{T}\times\varphi(T)\)
原式即\(=2\times\sum\limits_{T=1}^n\lfloor\dfrac{n}{T}\rfloor\times\lfloor\dfrac{m}{T}\rfloor\times\varphi(T) - n\times m\)
時間複雜度\(O(n)\)
code
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #define MogeKo qwq using namespace std; const int maxn = 1e5+10; const int N = 1e5; int phi[maxn],prime[maxn],cnt; long long n,m,sum[maxn]; bool vis[maxn]; void Phi() { sum[1] = phi[1] = 1; for(int i = 2; i <= N; i++) { if(!vis[i]) { phi[i] = i-1; prime[++cnt] = i; } for(int j = 1; j <= cnt && i*prime[j] <= N; j++) { vis[i*prime[j]] = true; if(i % prime[j]) phi[i*prime[j]] = phi[i] * (prime[j]-1); else { phi[i*prime[j]] = phi[i] * prime[j]; break; } } sum[i] = sum[i-1] + phi[i]; } } long long f(long long n,long long m) { long long ans = 0; if(n > m) swap(n,m); for(int i = 1,r; i <= n; i = r+1) { r = min(n/(n/i),m/(m/i)); ans += (n/i)*(m/i)*(sum[r]-sum[i-1]); } return 2 * ans - n*m; } int main() { scanf("%lld%lld",&n,&m); Phi(); printf("%lld",f(n,m)); return 0; }