0%

P2303 [SDOI2012] Longge 的问题

首先%%%zzz

人生中没做过几道数论题,经过 zzz 的悉心指导大概算是会了这道…题

题目要求为求

一道非常套路的题,感觉做这题可以总结出两个思想:

  • 向熟悉的函数进行化归
  • 拆解 gcd 的因数,考虑因数的贡献

这样就可以考虑对原式的每个因数考虑贡献,原式可以化为

因为 $gcd(n,m)=d$ 可以推出 $gcd(n/d,m/d)=1$,所以可以向欧拉函数化归:

发现后式就是欧拉函数定义式,因此直接推出:

刚学数论,另外需要注意:枚举因数从 $i$ 到 $i*i<=n$ 的时候,一下可以筛去两个因数,但是要考虑完全平方数是两个相同的因数的情况。

code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<bits/stdc++.h>
using namespace std;
long long eular(long long n){
long long ans=n;
for(long long i=2;i*i<=n;++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,ans=0;
cin>>n;
for(register long long i=1;i*i<=n;++i)
if(n%i==0)
if(i*i==n)ans+=i*eular(n/i);
else ans+=i*eular(n/i)+(n/i)*eular(i);
cout<<ans;
return 0;
}