51nod 1355 斐波那契的最小公倍数

1355 斐波那契的最小公倍数
题目来源: HackerRank
基准时间限制:3 秒 空间限制:131072 KB 分值: 640 难度:8级算法题 收藏 关注
斐波那契数列定义如下:

F(0) = 0 F(1) = 1
F(n) = F(n-1) + F(n-2)

给出n个正整数a1, a2,…… an,求对应的斐波那契数的最小公倍数,由于数字很大,输出Mod 1000000007的结果即可。
例如:1 3 6 9, 对应的斐波那契数为:1 2 8 34, 他们的最小公倍数为136。
Input
第1行:1个数N,表示数字的数量(2 <= N <= 50000)。
第2 至 N + 1行:每行1个数,对应ai。(1 <= ai <= 1000000)。
Output
输出Lcm(F(a1), F(a2) …… F(an)) Mod 1000000007的结果。
Input示例
4
1
3
6
9
Output示例
136


【分析】

终于把这破坑填了…
分析很麻烦…写起来倒是很不麻烦…

https://www.zhihu.com/question/61218881/answer/185333391?group_id=862696021547978752#comment-298061293

这道题告诉我们zhihu不只是用来划水的…还能用来学习


【代码】

//51nod 1355 斐波那契的最小公倍数
#include<bits/stdc++.h>
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=1000005;
const int mod=1e9+7;
bool vis[mxn];
int n,m,T,mx,ans=1;
int f[mxn],g[mxn];
inline int read()
{
    int x=0;char ch=getchar();
    while(ch<'0' || ch>'9') ch=getchar();
    while(ch>='0' && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    return x;
}
inline int ksm(int x,int k)
{
    if(k==1) return x;
    int tmp=ksm(x,k>>1);
    if(k&1) return (ll)tmp*tmp%mod*x%mod;
    else return (ll)tmp*tmp%mod;
}
inline void init()
{
    int i,j;
    f[1]=f[2]=1;
    fo(i,3,n) f[i]=(f[i-1]+f[i-2])%mod;
    fo(i,1,n) g[i]=f[i];
    fo(i,1,n)
    {
        int tmp=ksm(g[i],mod-2);
        for(j=i+i;j<=n;j+=i)
          g[j]=(ll)g[j]*tmp%mod;
    }
}
int main()
{
    int i,j,x;
    n=read();
    fo(i,1,n)
    {
        x=read();
        vis[x]=1;
        mx=max(mx,x);
    }n=mx;
    init();
    fo(i,1,n)
      for(j=i;j<=n;j+=i)
        if(vis[j])
        {
            ans=(ll)ans*g[i]%mod;
            break;
        }
    printf("%d\n",ans);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值