loj6102 「2017 山东二轮集训 Day1」第三题

Posted 逢山开路 遇水架桥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了loj6102 「2017 山东二轮集训 Day1」第三题相关的知识,希望对你有一定的参考价值。

传送门:https://loj.ac/problem/6102

【题解】

贴一份zyz在知乎的回答吧  https://www.zhihu.com/question/61218881

其实是经典问题

技术分享
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

const int N = 5e4 + 10, M = 1e6 + 10, F = 1e6;
const int mod = 1e9 + 7;

int n, a[N], f[F + 5], g[F + 5];
bool h[F + 5];

inline int pwr(int a, int b) {
    int ret = 1;
    while(b) {
        if(b&1) ret = 1ll * ret * a % mod;
        a = 1ll * a * a % mod;
        b >>= 1;
    }
    return ret;
}

int main() {
    cin >> n;
    for (int i=1; i<=n; ++i) scanf("%d", a+i);
    f[0] = 0, f[1] = g[1] = 1; 
    for (int i=2; i<=F; ++i) {
        f[i] = f[i-1] + f[i-2];
        if(f[i] >= mod) f[i] -= mod;
        g[i] = f[i];
    }
    for (int i=1; i<=F; ++i) {
        int t = pwr(g[i], mod-2);
        for (int j=i+i; j<=F; j+=i)
            g[j] = 1ll * g[j] * t % mod;
    }
    for (int i=1; i<=n; ++i) h[a[i]] = 1;
    int ans = 1;
    for (int i=1; i<=F; ++i) {
        for (int j=i+i; j<=F; j+=i) h[i] |= h[j];
        if(h[i]) {
//            cout << i << ‘ ‘ << g[i] << endl;
            ans = 1ll * ans * g[i] % mod;
        }
    }
    cout << ans;
    return 0;
}
View Code

 

以上是关于loj6102 「2017 山东二轮集训 Day1」第三题的主要内容,如果未能解决你的问题,请参考以下文章

「2017 山东一轮集训 Day6」子序列

矩阵[雅礼集训 2017 Day1]

Loj #6142. 「2017 山东三轮集训 Day6」A

LOJ6077「2017 山东一轮集训 Day7」逆序对 生成函数+组合数+DP

2017雅礼集训 Day1

loj6029 「雅礼集训 2017 Day1」市场