hdu 5382 GCD?LCM!

先考虑化简f函数

发现,f函数可以写成一个递归式,化简后可以先递推求出所有f函数的值,

所以可以先求出所有S函数的值,对于询问,O(1)回答

代码:

  //File Name: hdu5382.cpp
  //Author: long
  //Mail: 736726758@qq.com
  //Created Time: 2016年10月24日 星期一 11时03分18秒
                                   
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#define LL long long
using namespace std;
const int MAXN = 1000000 + 1;
const int MOD = 258280327;
LL S[MAXN],f[MAXN],g[MAXN],h[MAXN];
int prime[MAXN];
bool check[MAXN];
void cal_h(){
    memset(check,false,sizeof(check));
    h[1] = 1;
    int tot = 0;
    for(int i=2;i<MAXN;i++){
        if(!check[i]){
            prime[tot++] = i;
            h[i] = 2;
        }
        for(int j=0;j<tot;j++){
            if((LL)i * prime[j] >= MAXN) break;
            check[i * prime[j]] = true;
            if(i % prime[j] == 0){
                h[i * prime[j]] = h[i];
                break;
            }
            else
                h[i * prime[j]] = h[i] * 2 % MOD;
        }
    }
}
void cal_g(){
    for(int i=1;i<MAXN;i++){
        for(int j=i;j<MAXN;j+=i){
            (g[j] += h[j / i - 1]) %= MOD;
        }
    }
}
void cal_f(){
    for(int i=1;i<MAXN;i++)
        (f[i] = f[i-1] + 2 * i - 1 - g[i - 1] + MOD) %= MOD;
}
void cal_S(){
    for(int i=1;i<MAXN;i++)
        S[i] = (S[i-1] + f[i]) % MOD;
}
void init(){
    cal_h();
    cal_g();
    cal_f();
    cal_S();
}
int main(){
    init();
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        printf("%lld\n",S[n]);
    }
    return 0;
}
View Code

 

posted on 2016-10-26 14:44  _fukua  阅读(188)  评论(0编辑  收藏  举报