f(n) HDU 2582(找规律+筛素数+质因子分解详解)

HDU 2582 f(n)

 This time I need you to calculate the f(n) . (3<=n<=1000000)

f(n)= Gcd(3)+Gcd(4)+…+Gcd(i)+…+Gcd(n).
Gcd(n)=gcd(C[n][1],C[n][2],……,C[n][n-1])
C[n][k] means the number of way to choose k things from n some things.
gcd(a,b) means the greatest common divisor of a and b. 

Input
There are several test case. For each test case:One integer n(3<=n<=1000000). The end of the in put file is EOF.
Output
For each test case:
The output consists of one line with one integer f(n).
Sample Input

3
26983

Sample Output

3
37556486
题意:

给出公式 Gcd(n)=gcd(C[n][1],C[n][2],,C[n][n1]) G c d ( n ) = g c d ( C [ n ] [ 1 ] , C [ n ] [ 2 ] , … … , C [ n ] [ n − 1 ] )
让求 f(n)=Gcd(3)+Gcd(4)++Gcd(i)++Gcd(n) f ( n ) = G c d ( 3 ) + G c d ( 4 ) + … + G c d ( i ) + … + G c d ( n )

分析:

对于 G=gcd(C1n,C2nC3n...Cn1n) G = g c d ( C n 1 , C n 2 , C n 3 . . . C n n − 1 ) 来说

有且仅有以下三种情况:

(1) 如果n为素数, G=n G = n

(2) 如果n有两个或两个以上的素因子, G=1 G = 1

(3) 如果n只有一个素因子 p p G=p


为什么会这样呢
下面一一进行分析:

例子:n = 5
51   5×42×1   5×4×33×2×1   5×4×3×24×3×2×1 5 1       5 × 4 2 × 1       5 × 4 × 3 3 × 2 × 1       5 × 4 × 3 × 2 4 × 3 × 2 × 1

我们首先把组合数按照分数形式写出来(不约分化简)会发现,最大公因数必须是和分子上的n相关的,即n的因子(包括它本身),其最大公因数最大为n,为什么?

因为观察分子处n之外的其他数在每个组合数中是逐渐增加的,即第一个只有n这个数本身,第二个相比前一个多乘了一个n-1,第三个相比前一个多乘了n-2,这样最大公因数必须是共有的,所以一定不能在这些数里面找,所以必定是n或n的因数,因此下面的分析我们只对n进行考虑就可以了

明白了上面的分析

这个问题分析的关键便是分母对于分子上n的影响了

(1) 如果n为素数, G=n G = n :
举个例子,拿5来说我们要求

51   5×42×1   5×4×33×2×1   5×4×3×24×3×2×1 5 1       5 × 4 2 × 1       5 × 4 × 3 3 × 2 × 1       5 × 4 × 3 × 2 4 × 3 × 2 × 1

的最大公因数

组合数的分母实际上会最终便利 [1,n1] [ 1 , n − 1 ] ,但是由于n是素数,所以找不到一个因子会使得n变化,也就是说分子上的n经过约分化简后仍然是n,这样最大公因数一定是n。
正如举得例子,因为5是素数,所以分母1,2,3,4都不能约分5,最终5不会变,因此最大公因数是5

(2) 如果n有两个或两个以上的素因子, G=1 G = 1 :

举个例子拿6来说
因为6含有2个质因子2和3,因为组合数的分母会遍历完1-5,也就一定会遍历到2和3

61   6×52×1   6×5×43×2×1   6×5×4×34×3×2×1   6×5×4×3×25×4×3×2×1 6 1       6 × 5 2 × 1       6 × 5 × 4 3 × 2 × 1       6 × 5 × 4 × 3 4 × 3 × 2 × 1       6 × 5 × 4 × 3 × 2 5 × 4 × 3 × 2 × 1

这样一定存在一个组合数,分母有2,使得6消去了2剩下了3,也一定存在一个组合数,分母有3,使得6消去了3只剩下2,因为这两个组合数的存在,6约分后剩下的两个素因子是互质的,这样这两个组合数的最大公因数一定为1,从而导致所有6的组合数的最大公因子都是1

(3) 如果n只有一个素因子 p p G=p:
首先明确含有一个素因子的话说明一定是素数幂的形式即 pk p k
因为如果不是要么是第一种情况,他就是素数,要么是第二种情况还有别的素因子(算术基本定理任何数可以分解成素数的乘积)

假设 n=pk n = p k 分母在便利1到n-1的过程中,一定会有一个组合数的分母含有一个 p,p2,...pk1 p , p 2 , . . . p k − 1
这就会使得分子上的n经过约分后变成了
pk,pk1,pk2,...p p k , p k − 1 , p k − 2 , . . . p
这样他们的最大公因数必然是p

举个例子拿4来说
41   4×32×1   4×3×23×2×1 4 1       4 × 3 2 × 1       4 × 3 × 2 3 × 2 × 1


因此,对于一个所给的数n,我们先判断一下是否是素数,是素数直接加本身,不是素数进行质因子分解,超过两个质因子就加1,只有一个质因子就加这个质因子,分别利用筛素数+质因子分解+打表
然后O(1)输出答案

code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
ll prime[maxn];
bool isprime[maxn];
int cnt;
void init(){
    memset(isprime,true,sizeof(isprime));
    for(int i = 2; i < maxn; i++){
        if(isprime[i]){
            prime[cnt++] = i;
            for(int j = i+i; j < maxn; j += i){
                isprime[j] = false;
            }
        }
    }
}
ll resolve(int n){
    int k;
    int num = 0;
    for(int i = 0; i < cnt && prime[i] * prime[i] <= n; i++){
        if(n % prime[i] == 0){
            num++;
            if(num > 1) return 1;
            k = prime[i];
            while(n % prime[i] == 0) n /= prime[i];
        }
    }
    if(num == 1 && n == 1) return k;
    if(num == 0 && n > 1) return n;
    return 1;
}
ll f[maxn];
void get(){
    init();
    f[2] = 0;
    for(int i = 3; i < maxn; i++){
        if(isprime[i]) f[i] = f[i-1] + i;
        else f[i] = f[i-1] + resolve(i);
    }
}
int main(){
    get();
    int n;
    while(~scanf("%d",&n)){
        printf("%lld\n",f[n]);
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值