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

USACO GCD Extreme(II)

时间:2016-08-22 00:27:58      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:求gcd(1,2)+gcd(1,3)+gcd(2,3)+...+gcd(n-1,n)

-----------------------------------------------------------------

设f(i)=gcd(1,n)+...+gcd(n-1,n),则答案S(n)=f(2)+...+f(n)

如何求f

设g(n,i)表示满足gcd(x,n)=1且x<n的x个数,则f(n)=sum{i*g(n,i):i|n}

gcd(x,n)=i的充要条件是x/i和n/i互质,所以gcd(n,i)=phi(n/i)

计算一片f用类似筛法的方法

------------------------------------

 

LuoguP2398题目描述

 

for i=1 to n 

 

for j=1 to n

 

 sum+=gcd(i,j)

 

给出n求sum. gcd(x,y)表示x,y的最大公约数.

----------------------------------------

很类似,在加上一个nf=gcd(1,n)+...+gcd(n,n)  f和nf加起来就行了

 

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll n,ans=0;

int phi[N];
void phiTable(int n){
    phi[1]=1;
    for(int i=2;i<=n;i++) if(!phi[i])
        for(int j=i;j<=n;j+=i){
            if(!phi[j]) phi[j]=j;
            phi[j]=phi[j]/i*(i-1);
        }
}

ll f[N],nf[N];
int main(int argc, const char * argv[]) {
    cin>>n;
    phiTable(n);
    
    for(int i=1;i<=n;i++)
        for(int j=i;j<=n;j+=i){
            nf[j]+=i*phi[j/i];
            if(j!=i) f[j]+=i*phi[j/i];
        }
    for(int i=1;i<=n;i++) ans+=f[i]+nf[i];
    cout<<ans;
    
    return 0;
}

 

USACO GCD Extreme(II)

标签:

原文地址:http://www.cnblogs.com/candy99/p/5793938.html

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