jzoj_斐波那契_2

Description
  小明有一个数列。
  a[0] = a[1] = 1。
  a[i] = i * a[i - 1] * a[i - 2](i≥2)。
  小明想知道a[n]的因子个数。

Input
  输入仅一个正整数n。

Output
  输出a[n]的因子个数mod 1,000,000,007的值。

Sample Input
  3

Sample Output
  4

Hint
  【数据范围】
  对于30%的数据满足0≤n≤1,000。
  对于100%的数据满足0≤n≤1,000,000。


筛素因子个数和可太骚了

利用埃式筛法非线性的缺点,

就是每个合数都会被她的所有苏影子筛一遍,

这道题就从苏影子出发,枚举包含苏影子的和数

#include<iostream>
#include<cstdio>

#define ri register int
#define u long long

namespace opt {

    inline u in() {
        u x(0),f(1);
        char s(getchar());
        while(s<'0'||s>'9') {
            if(s=='-') f=-1;
            s=getchar();
        }
        while(s>='0'&&s<='9') {
            x=(x<<1)+(x<<3)+s-'0';
            s=getchar();
        }
        return x*f;
    }

}

using opt::in;

#define NN 1000005
#define MO 1000000007

#include<cmath>
#include<cstring>

namespace mainstay {
    u num,low[NN],p[NN],f[NN]= {0,1,1};

    void pri(const u &N) {
        for(ri i(2); i<=N; ++i) {
            if(!low[i]) {
                p[++num]=i,low[i]=i;
            }
            for(ri j(1); j<=num; ++j) {
                if(p[j]>low[i]||p[j]>N/i) break;
                low[p[j]*i]=p[j];
            }
        }
    }
    
    u a[NN],ans(1);

    inline void solve() {
        u N(in());
        pri(N);
        if(N==0&&N==1) printf("%d",1);
        for(ri i(2); i<=N; ++i) f[i]=(f[i-1]+f[i-2])%MO;
        for(ri i(1); i<=num; ++i) {
            for(ri j(1);p[i]*j<=N;++j){
                u _x(p[i]*j),_t(f[N+1-_x]);
                while(!(_x%p[i])){
                    _x/=p[i],a[i]=(a[i]+_t)%MO;
                }
            }
        }
        for(ri i(1); i<=num; ++i) ans=(ans*((a[i]+1)%MO))%MO;
        std::cout<<ans;
    }

}

int main() {

    //freopen("fiborial.in","r",stdin);
    //freopen("fiborial.out","w",stdout);
    mainstay::solve();

}

猜你喜欢

转载自www.cnblogs.com/ling-zhi/p/11752142.html