BZOJ 2705: [SDOI2012]Longge的问题 GCD

2705: [SDOI2012]Longge的问题

Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://www.lydsy.com/JudgeOnline/problem.php?id=2705

Description

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

Input

一个整数,为N。

Output

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

Sample Input

6

Sample Output

15

HINT

 

题意

 

题解

题解:http://hzwer.com/3470.html

题目中要求出∑gcd(i,N)(1<=i<=N)。

枚举n的约数k,令s(k)为满足gcd(m,n)=k,(1<=m<=n)m的个数,则ans=sigma(k*s(k)) (k为n的约数)

因为gcd(m,n)=k,所以gcd(m/k,n/k)=1,于是s(k)=euler(n/k)

phi可以在根号的时间内求出

代码:

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <bitset>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 200051
#define mod 10007
#define eps 1e-9
int Num;
//const int inf=0x7fffffff;   //нчоч╢С
const int inf=0x3f3f3f3f;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
//**************************************************************************************

ll n;
int m;
ll phi(ll x)
{
    ll t=x;
    for(ll i=2;i<=m;i++)
    {
        if(x%i==0)
        {
            t=t/i*(i-1);
            while(x%i==0)x/=i;
        }
    }
    if(x>1)t=t/x*(x-1);
    return t;
}
int main()
{
    cin>>n;
    ll ans=0;
    m = sqrt(n);
    for(int i=1;i<=sqrt(n);i++)
    {
        if(n%i==0)
        {
            ans+=i*phi(n/i);
            if(i*i<n)
                ans+=(ll)(n/i)*phi(i);
        }
    }
    cout<<ans<<endl;
}

 

posted @ 2015-08-30 15:24  qscqesze  阅读(297)  评论(0编辑  收藏  举报