Live2D

斐波那契的最小公倍数 题解

题目传送门

题目大意

给出 n 以及一个长度为 n 的数组 a1,2,...,n ,定义 fi 表示斐波拉契数列的第 i 项,其中 f1=f2=1 。求出 lcm{fa1,fa2,...,fan}

n5×104,ai106

思路

算是让我见识了 min-max 容斥有多强。做这道题首先你得知道一个知道一个式子:

lcm{S}=TSgcd{T}(1)|T|+1

具体证明可以考虑我们对于质因数分解的每一位做 min-max 容斥。

然后看到这道题,我们又有一个人尽皆知的定理 gcd(fi,fj)=fgcd(i,j),然后就可得到:

lcm{S}=TSfgcd{T}(1)|T|+1

=i=1fiTS[gcd{T}=i](1)|T|+1

然后上面那一坨不是很好求,所以我们可以考虑莫比乌斯反演解决,我们设 ai=TS[gcd{T}=i](1)|T|+1bi=i|dad,那么我们可以得到:

bi=TS[i|gcd{T}](1)|T|+1

然后你发现如果 iT 中出现过,那么 bi=1,反之为 0,具体证明可以使用二项式定理。

然后我们使用莫比乌斯反演可以得到:

ai=i|dμ(di)bd

然后直接预处理之后暴力算就好了,时间复杂度为 Θ(wlnw) ,其中 w 是值域。

Code

Copy
#include <bits/stdc++.h> using namespace std; #define Int register int #define mod 1000000007 #define MAX 1000000 int n,tot,f[MAX + 5],a[MAX + 5],b[MAX + 5],mu[MAX + 5],vis[MAX + 5],prime[MAX + 5]; void Euler (int up){ mu[1] = 1; for (Int i = 2;i <= up;++ i){ if (!vis[i]) prime[++ tot] = i,mu[i] = -1; for (Int j = 1;j <= tot && i * prime[j] <= up;++ j){ vis[i * prime[j]] = 1; if (i % prime[j] == 0) break; else mu[i * prime[j]] = -mu[i]; } } } int qkpow (int a,int b){ int res = 1;for (;b;b >>= 1,a = 1ll * a * a % mod) if (b & 1) res = 1ll * res * a % mod; return res; } template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;} template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);} template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');} signed main(){ read (n),Euler (MAX); for (Int i = 1,x;i <= n;++ i) read (x),b[x] = 1; for (Int i = 1;i <= MAX;++ i) for (Int j = i + i;j <= MAX;j += i) b[i] |= b[j]; f[1] = f[2] = 1;for (Int i = 2;i <= MAX;++ i) f[i] = (f[i - 1] + f[i - 2]) % mod; for (Int i = 1;i <= MAX;++ i) for (Int j = i;j <= MAX;j += i) a[i] += mu[j / i] * b[j]; int ans = 1;for (Int i = 1;i <= MAX;++ i) ans = 1ll * ans * qkpow (f[i],mod - 1 + a[i]) % mod; write (ans),putchar ('\n'); return 0; }
posted @   Dark_Romance  阅读(265)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示