BZOJ 2705: [SDOI2012]Longge的问题 [欧拉函数]

2705: [SDOI2012]Longge的问题

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 2553  Solved: 1565
[Submit][Status][Discuss]

Description

Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。

Input

一个整数,为N。

Output

一个整数,为所求的答案。

Sample Input

6

Sample Output

15

HINT

【数据范围】

对于60%的数据,0<N<=2^16。

对于100%的数据,0<N<=2^32。


gcd(i,n)=x

gcd(i/x,n/x)=1

又是欧拉函数

答案为sigma{phi(n/x)*x|x是n的约数}

这个欧拉函数需要一个个算(保存不开,也没必要)

注意枚举约数的方法,sqrt(n),特判n为平方数

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=;
ll n,p[N],m;
ll ans;
void fac(){
ll s=sqrt(n);
for(int i=;i<=s;i++){
if(n%i==) p[++m]=i,p[++m]=n/i;
}
if(s*s==n) m--;
}
ll phi(ll n){
ll s=sqrt(n),ans=n;
for(ll i=;i<=s;i++) if(n%i==){
ans=ans/i*(i-);
while(n%i==) n/=i;
}
if(n>) ans=ans/n*(n-);
return ans;
}
int main(){
scanf("%lld",&n);
fac();
for(int i=;i<=m;i++) ans+=phi(n/p[i])*p[i];
printf("%lld",ans);
}
上一篇:C# 数据结构--单链表


下一篇:《深入理解Java虚拟机》学习笔记