第七行的解释写的不好,看下面我有重新写。
令
,可以得到所有小于i并且跟i互素的数乘以m均与n的gcd计算结果为m
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
int main()
{
ll n;
while(scanf("%lld",&n)!=EOF){
ll ans=n;
///循环变量必须改用long long 否则会导致TLE,因为可能有数据平方后大于long long
for(ll i=2;i*i<=n;i++){
int num=0;
if(n%i==0){
while(n%i==0){
num++;
n/=i;
}
ans=ans+ans*num*(i-1)/i;
}
}
if(n>1) ans=ans+ans*(n-1)/n;
printf("%lld\n",ans);
}
return 0;
}
其实这个题如果不知道积性函数单纯的能推出我上面重新写的那个结论,通过折半枚举也能写出来,代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
ll phi(ll n){
ll ans=n;
for(ll 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()
{
ll n;
while(scanf("%lld",&n)!=EOF){
ll ans=0;
for(ll i=1;i*i<=n;i++){
if(n%i==0){
ans+=phi(i)*n/i;
if(i*i<n)
ans+=phi(n/i)*i;
}
}
printf("%lld\n",ans);
}
return 0;
}