BZOJ4833 [Lydsy1704月赛]最小公倍佩尔数
题意
已知\(e_n+\sqrt2f_n=(1+\sqrt2)^n\),\(e_n-\sqrt2f_n=(1-\sqrt2)^n\),\(g_n=lcm_{i=1}^nf_i\),求\(\sum_{i=1}^{n}g_i\times i\)
首先可以得到\(e_{n-1}+\sqrt2f_{n-1}=(1+\sqrt2)^{n-1}\)
那么$e_n+\sqrt2f_n=(1+\sqrt2)(e_{n-1}+\sqrt2f_{n-1})
=(e_{n-1}+2f_{n-1})+\sqrt2(e_{n-1}+f_{n-1})$
即\(e_n=e_{n-1}+2f_{n-1}\),\(f_n=e_{n-1}+f_{n-1}\)
继续往下推:\(f_n=e_{n-2}+2f_{n-2}+f_{n-1}=2f_{n-1}+f_{n-2}\)
把\(0,1\)代入题面的两个式子可以解出\(f_0=0,f_1=1\)。
所以我们可以\(O(n)\)求出所有\(f\)的值。
这里有一个性质:
\[f_n=2f_{n-1}+f_{n-2}\\
=5f_{n-2}+2f_{n-3}\\
=12f_{n-3}+5f_{n-4}\\
...\\
=f_mf_{n-m+1}+f_{m-1}f_{n-m}
\]
接下来把\(g\)反演一波,设\(S={\{}1,2,...,n{\}}\)。
\[g_n=lcm_{i=1}^nf_i=
\prod_{T\subseteq S,T\neq \emptyset}gcd(f(T))^{(-1)^{|T|+1}}
\]
根据刚才\(f\)的性质可以得到:
\[gcd(f_n,f_m)=gcd(f_mf_{n-m+1}+f_{m-1}f_{n-m},f_m)=gcd(f_{m-1}f_{n-m},f_m)\\
\because gcd(f_{m-1},f_m)=1\\
\therefore gcd(f_{m-1}f_{n-m},f_m)=gcd(f_{n-m},f_m)\\
gcd(f_n,f_m)=gcd(f_{n-m},f_m)
\]
那么往下写可以发现:
\[gcd(f_n,f_m)=gcd(f_{n-m},f_m)=gcd(f_{n-2m},f_m)=...=gcd(f_{n\mod m},f_m)
\]
继续算的话我们会用\(n\mod m\)和\(m\)较大的一个减较小的一个,重复上面的过程......
可以发现最后就是\(gcd(f_{gcd(n,m)},f_0)=f_{gcd(n,m)}\)
所以\(gcd(f_n,f_m)=f_{gcd(n,m)}\)
回到反演\(g\)的式子:
\[g_n=\prod_{T\subseteq S,T\neq \emptyset}gcd(f(T))^{(-1)^{|T|+1}}
=\prod_{T\subseteq S,T\neq \emptyset}f_{gcd(T)}^{(-1)^{|T|+1}}\\
=\prod_{d=1}^n\prod_{T\subseteq S,T\neq \emptyset}
[gcd(T)=d]f_d^{(-1)^{|T|+1}}\\
=\prod_{d=1}^nf_d^{\sum_{T\subseteq S,T\neq \emptyset}
[gcd(T)=d](-1)^{|T|+1}}
\]
把指数部分拎出来,设$h_d=\sum_
gcd(T)=d{|T|+1}$,再设$t_k=\sum_{k|d}h_d$,那么
\[t_k=\sum_{T\subseteq S,T\neq \emptyset}
[k|gcd(T)](-1)^{|T|+1}
\]
考虑\(S\)中每个元素的贡献,设\(m=\frac{n}{k}\),那么
\[t_k=\sum_{i=1}^{m}{m\choose i}(-1)^{i+1}\\
=-\sum_{i=1}^{m}{m\choose i}(-1)^i\\
=-\sum_{i=0}^{m}{m\choose i}(-1)^i+1=1
\]
再对\(h\)反演一下:$h_k=\sum_{k|d}^{n}\mu_{\frac{d}{k}}t_k=
\sum_{k|d}^{n}\mu_{\frac{d}{k}}$
代回\(g_n\)的式子就是:
\[g_n=\prod_{i=1}^{n}f_i^{h_k}=
\prod_{i=1}^{n}f_i^{\sum_{k|d}^{n}\mu_{\frac{d}{k}}}=
\prod_{i=1}^{n}(\prod_{d|i}^{n}f_d^{\mu_{\frac{i}{d}}})
\]
所以只需要算出\(\prod_{d|i}^{n}f_d^{\mu_{\frac{i}{d}}}\)即可。这个也很好算,对于每个\(d\),把每个\(d\)的倍数\(kd\)对应的\(g_{kd}\)乘上\(f_d\)即可。时间复杂度为\(O(\sum_{i=1}^{n}\frac{n}{i})=O(nlogn)\)
#include<bits/stdc++.h>
#define rg register
#define il inline
#define cn const
#define gc getchar()
#define fp(i,a,b) for(rg int i=(a),ed=(b);i<=ed;++i)
using namespace std;
typedef cn int cint;
il int rd(){
rg int x(0),f(1); rg char c(gc);
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=gc; }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=gc;
return x*f;
}
cint maxn=1000010;
int T,n,mod;
int isnp[maxn],mu[maxn],pri[maxn],cnt;
int f[maxn],inv[maxn],g[maxn],ans;
il void calc_mu(cint &n){
mu[1]=1;
fp(i,2,n){
if(!isnp[i])mu[i]=-1,pri[++cnt]=i;
for(rg int j=1;j<=cnt&&pri[j]*i<=n;++j){
isnp[pri[j]*i]=1;
if(i%pri[j]==0)break;
mu[i*pri[j]]=-mu[i];
}
}
}
il int fpow(int a,int b,int ans=1){
for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod;
return ans;
}
int main(){
calc_mu(1000000);
T=rd();
while(T--){
n=rd(),mod=rd();
f[1]=1; fp(i,2,n)f[i]=(2ll*f[i-1]%mod+f[i-2])%mod;
fp(i,1,n)inv[i]=fpow(f[i],mod-2);
fp(i,1,n)g[i]=1;
fp(i,1,n){
for(rg int j=i;j<=n;j+=i){
if(mu[j/i]>0)g[j]=1ll*g[j]*f[i]%mod;
if(mu[j/i]<0)g[j]=1ll*g[j]*inv[i]%mod;
}
}
fp(i,2,n)g[i]=1ll*g[i]*g[i-1]%mod;
ans=0; fp(i,1,n)ans=(ans+1ll*g[i]*i%mod)%mod;
printf("%d\n",ans);
}
return 0;
}