先考虑化简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 ",S[n]); } return 0; }