• 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 imes 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_{Tsubseteq S,T eq 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)\ ecause gcd(f_{m-1},f_m)=1\ herefore 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_{nmod m},f_m) ]

    继续算的话我们会用(nmod 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_{Tsubseteq S,T eq emptyset}gcd(f(T))^{(-1)^{|T|+1}} =prod_{Tsubseteq S,T eq emptyset}f_{gcd(T)}^{(-1)^{|T|+1}}\ =prod_{d=1}^nprod_{Tsubseteq S,T eq emptyset} [gcd(T)=d]f_d^{(-1)^{|T|+1}}\ =prod_{d=1}^nf_d^{sum_{Tsubseteq S,T eq emptyset} [gcd(T)=d](-1)^{|T|+1}} ]

    把指数部分拎出来,设$h_d=sum_{Tsubseteq S,T eq emptyset}

    gcd(T)=d{|T|+1}$,再设$t_k=sum_{k|d}{n}h_d$,那么

    [t_k=sum_{Tsubseteq S,T eq emptyset} [k|gcd(T)](-1)^{|T|+1} ]

    考虑(S)中每个元素的贡献,设(m=frac{n}{k}),那么

    [t_k=sum_{i=1}^{m}{mchoose i}(-1)^{i+1}\ =-sum_{i=1}^{m}{mchoose i}(-1)^i\ =-sum_{i=0}^{m}{mchoose 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
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    手把手教您玩转信用卡 如何“以卡养卡”合法“套现”
    267家已获第三方许可机构名单查询
    C#生成图片验证码
    File I/O
    文件上传代码
    集合框架
    接口
    多态
    封装
    jsp做成mvc模式的代码
  • 原文地址:https://www.cnblogs.com/akura/p/12246131.html
Copyright © 2020-2023  润新知