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
【分析】
终于把这破坑填了…
分析很麻烦…写起来倒是很不麻烦…
这道题告诉我们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;
}