码迷,mamicode.com
首页 > 其他好文 > 详细

P2303 [SDOi2012]Longge的问题

时间:2018-09-22 01:04:00      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:for   注意   c++   描述   str   family   需要   region   cout   

题目描述

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

输入输出格式

输入格式:

一个整数,为N。

输出格式:

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

输入输出样例

输入样例#1: 
6
输出样例#1: 
15

说明

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

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

 

Solution:

  本题数学。

  设$f(x)$表示范围内$gcd(i,j)=x$的数的个数,则$f(x)=\sum_\limits{i=1}^{i\leq n}{(gcd(i,n)=x)}\;=\;\sum_\limits{i=1}^{i\leq \frac{n}{x}}{x*(gcd(i,\frac{n}{x})=1)}\;=\;x*\varphi (\frac{n}{x})$。

  所以原式$=\sum_\limits{i|n}^{i\leq n}{i*\varphi (\frac{n}{i})}$。

  于是直接暴力根号枚举n的因子,然后暴力根号筛$\varphi$ 求解就好了,时间复杂度$O(n^{\frac{3}{4}})$(注意开long long,被坑惨了)。

代码:

/*Code by 520 -- 9.20*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
ll n;
ll ans;

ll phi(ll x){
    ll ans=x;
    for(ll i=2;i*i<=x;i++)
        if(x%i==0) {
            while(x%i==0) x/=i;
            ans=ans/i*(i-1);
        }
    if(x>1) ans=ans/x*(x-1);
    return ans;
}

int main(){
    cin>>n;
    ll i=1;
    for(i=1;i*i<n;i++)
        if(n%i==0) ans+=i*phi(n/i)+(n/i)*phi(i);
    if(i*i==n) ans+=i*phi(i);
    cout<<ans;
    return 0;
}

 

P2303 [SDOi2012]Longge的问题

标签:for   注意   c++   描述   str   family   需要   region   cout   

原文地址:https://www.cnblogs.com/five20/p/9688721.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!