hdu 2582(数论相关定理+素数筛选+整数分解)

f(n)

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 457    Accepted Submission(s): 279


Problem Description
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
这题要用到这个公式:
,那么G的值为:


n为素数:本身

n有多个素因子:1

n只有一个素因子:该因子

920MS才跑过去。。没优化了。。记得用_int64保存结果。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;

const int N = 1000001;
bool p[N];
LL g[N];
LL f[N];
void init(){
    memset(g,0,sizeof(g));
    for(int i=2;i<N;i++){
        if(!p[i]){
            g[i]=(LL)i;
            for(LL j = (LL)i*i;j<N;j+=i){
                p[j] = true;
            }
        }
    }
    f[2]=0;
    for(int i=3;i<N;i++){
        int cnt = 0;
        if(g[i]==0){
            int temp=-1;
            int n = i;
            for(int j=2;j*j<=n;j++){
                if(n%j==0){
                    temp=(LL)j;
                    cnt++;
                    while(n%j==0){
                        n/=j;
                    }
                }
            }
            if(n>1) {temp=(LL)n,cnt++;}
            if(cnt!=1) g[i]=1;
            if(cnt==1) g[i]=(LL)temp;
        }
        f[i]=f[i-1]+g[i];
    }
}
int main()
{
    init();
    int n;
    while(~scanf("%d",&n)){
        printf("%lld\n",f[n]);
    }
    return 0;
}

 

 

posted @ 2016-05-26 10:33  樱花庄的龙之介大人  阅读(308)  评论(0编辑  收藏  举报