题解 luogu.P2303 [SDOI2012] Longge 的问题
题目
luogu.P2303 [SDOI2012] Longge 的问题
比较套路化的推式子,但是需要理解具体的过程。故而写一篇题解,具体分析一下。
题意建模
给定一个整数 \(n\),你需要求出 \(\sum\limits_{i=1}^n \gcd(i, n)\),其中 \(\gcd(i, n)\) 表示 \(i\) 和 \(n\) 的最大公因数。
- 对于 $60% $ 的数据,保证 \(n\leq 2^{16}\)。
- 对于 $100% $ 的数据,保证 \(1\leq n< 2^{32}\)。
算法分析
部分分解法
暴力,直接照着题意模拟即可。
正解
给定整数 $ n $,洛谷题目 P2303 要求计算表达式 \(\sum_{i=1}^n \gcd(i, n)\) 的值。以下是推导该公式的详细过程:
-
枚举约数重构表达式:
由于 \(\gcd(i, n)\) 的值一定是 $ n$ 的约数,可以将原式改写为枚举约数 $ d $ 的形式:\( \sum_{d \mid n} d \cdot \left| \{ i : \gcd(i, n) = d \} \right| \)
其中 \(d\) 遍历 \(n\) 的所有正约数,内部部分表示满足 \(\gcd(i, n) = d\) 的整数 $ i $ 的数量。
-
转化为欧拉函数:
若 \(\gcd(i, n) = d\),则等价于 \(\gcd(i/d, n/d) = 1\),且 \(i/d\) 和 $ n/d $ 均为整数。因此,满足条件的 $ i $ 的数量等于不超过 $ n/d $ 且与 $n/d $ 互质的数的个数,即欧拉函数 \(\phi(n/d)\):\( \sum_{d \mid n} d \cdot \phi(n/d) \)
此形式已可直接用于计算(例如枚举 $ n $ 的约数并求值)。
总结推导核心:原始求和 \(\sum \gcd(i, n)\) 被转化为约数求和形式 \(\sum_{d \mid n} d \cdot \phi(n/d)\),适用于编程求解。
所以现在就可以预处理出来质数(线性筛),然后试除法求欧拉函数。时间复杂度:
\(O(\text{质数的个数} \times \sqrt n\ )\),足以通过本题。
参考代码
暴力(70pts)
#include<iostream>
using namespace std;
int gcd(int x,int y) { return y?gcd(y,x%y):x; }
int n;
int main()
{
cin>>n;
long long ans=0;
for(int i=1;i<=n;i++)
ans+=gcd(i,n);
cout<<ans<<endl;
return 0;
}
正解
#include<iostream>
#include<cstring>
#include<cmath>
#define rei register int
using namespace std;
const int N=(1<<16)+5;
int pri[N],idx;
bool is_pri[N];
void get_pri(int n)
{
memset(is_pri,true,sizeof(is_pri));
is_pri[0]=is_pri[1]=false;
for(rei i=2;i<=n;i++)
{
if(is_pri[i]) pri[++idx]=i;
for(rei j=1;i*pri[j]<=n;j++)
{
is_pri[i*pri[j]]=false;
if(i%pri[j]==0) break;
}
}
}
long long get_phi(long long n)
{
long long ans=n;
for(rei i=2;i<=n/i;i++)
if(n%i==0)
{
ans=ans/i*(i-1);
while(n%i==0) n/=i;
}
if(n>1) ans=ans/n*(n-1);
return ans;
}
int main()
{
long long n; cin>>n;
get_pri(ceil(sqrt(n)));
long long ans=0;
for(rei i=1;i<=n/i;i++)
if(n%i==0)
{
ans+=i*get_phi(n/i);
if(i*i!=n) ans+=n/i*get_phi(i);
}
cout<<ans<<endl;
return 0;
}
细节实现
这个题,\(n\) 也要开long long。这是一个极易错的点。
总结归纳
在解有关 \(\gcd()\) 的问题时,可能会转化成欧拉函数的形式。同时我们前面探讨过,有一个贡献观点,这个时候,往往数据范围异常地大,这个时候就是利用上述的观点转化。还是要多练!!这种类型的题目不在少数,所以可以通过多做培养经验。继续努力!!!

浙公网安备 33010602011771号