zoukankan      html  css  js  c++  java
  • Codeforces 392C. Yet Another Number Sequence 题解

    题目链接:C. Yet Another Number Sequence

    题目大意:令 (F_1=1,F_2=2,F_n=F_{n-1}+F_{n-2}(nge 3),A_i(k)=F_i imes i^k) ,求 (sum_{i=1}^{n} A_i(k))

    (nleq 10^{17},kleq 40)

    Bonus: (kleq 200)


    题解:我们令 (f(n,k)=sum_{i=1}^{n} F_i imes i^k) ,接下来划一波式子:

    为了方便起见,令 (F_0=1,F_{-1}=0)

    [f(n,j)=sum_{i=1}^{n} (F_{i-1}+F_{i-2}) imes i^k \ =sum_{i=1}^{n} F_{i-1} imes i^k +sum_{i=1}^{n} F_{i-2} imes i^k \ =sum_{i=1}^{n} F_{i-1}sum_{j=0}^{k} inom{k}{j} (i-1)^j+sum_{i=1}^{n} F_{i-2} sum_{j=0}^{k} inom{k}{j} (i-2)^j 2^{k-j} \ =sum_{j=0}^{k} inom{k}{j}sum_{i=0}^{n-1} F_{i} imes i^j + 1 +sum_{j=0}^{k}inom{k}{j} 2^{k-j}sum_{i=1}^{n-2}F_i imes i^j +2^k \ =sum_{j=0}^{k} inom{k}{j} f(n-1,j)+sum_{j=0}^{k} inom{k}{j}2^{k-j}f(n-2,j) +2^k+1]

    划到这一步我们就可以直接矩阵快速幂了,矩阵大小为 ((2k+3) imes (2k+3)) ,时间复杂度 (O(k^3log n))

    接下来我们考虑 Bonus 中的数据范围怎么做。

    我们令 (G) 为斐波那契数列的转移矩阵, (f(n,k)=sum_{i=1}^{n} G^{i} imes i^k)

    那么我们考虑从 (f(n,k)) 拓展到 (f(2n,k))

    [f(2n,k)=sum_{i=0}^{2n}G^{i} imes i^k \ =sum_{i=0}^{n}G^i imes i^k + G^nsum_{i=0}^{n}G^i imes (i+n)^k \ =f(n,k)+G^nsum_{i=0}^{n}G^isum_{j=0}^{k}inom{k}{j}i^jn^{k-j} \ =f(n,k)+G^nsum_{j=0}^{k}inom{k}{j}n^{k-j}sum_{i=0}^{n}G^ii^j \ =f(n,k)+G^nsum_{j=0}^{k}inom{k}{j}n^{k-j}f(n,j)]

    直接递归下去处理即可,时间复杂度 (O(k^2log n + 8klog n))

    接下来是代码:

    (O(k^3log n))

    #include <cstdio>
    typedef long long ll;
    const int Maxk=40;
    const int Mod=1000000007;
    int C[Maxk+5][Maxk+5];
    int pow_2[Maxk+5];
    ll n;
    int k;
    int len;
    void init(){
    	pow_2[0]=1;
    	C[0][0]=1;
    	for(int i=1;i<=k;i++){
    		C[i][0]=C[i][i]=1;
    		for(int j=1;j<i;j++){
    			C[i][j]=(C[i-1][j]+C[i-1][j-1])%Mod;
    		}
    	}
    	for(int i=1;i<=k+1;i++){
    		pow_2[i]=(pow_2[i-1]<<1)%Mod;
    	}
    }
    struct Matrix{
    	int a[2*Maxk+5][2*Maxk+5];
    	void init(){
    		for(int i=0;i<len;i++){
    			a[i][i]=1;
    		}
    	}
    	friend Matrix operator *(Matrix a,Matrix b){
    		Matrix ans;
    		for(int i=0;i<len;i++){
    			for(int j=0;j<len;j++){
    				ans.a[i][j]=0;
    				for(int k=0;k<len;k++){
    					ans.a[i][j]=(ans.a[i][j]+1ll*a.a[i][k]*b.a[k][j])%Mod;
    				}
    			}
    		}
    		return ans;
    	}
    }trans,ans;
    Matrix quick_power(Matrix a,ll b){
    	Matrix ans;
    	ans.init();
    	while(b){
    		if(b&1){
    			ans=ans*a;
    		}
    		a=a*a;
    		b>>=1;
    	}
    	return ans;
    }
    int main(){
    	scanf("%lld%d",&n,&k);
    	init();
    	len=(k<<1)+3;
    	ans.a[0][0]=1;
    	trans.a[0][0]=1;
    	for(int i=0;i<=k;i++){
    		ans.a[0][i+1]=1;
    	}
    	for(int i=k+2;i<len;i++){
    		trans.a[i-(k+1)][i]=1;
    	}
    	for(int i=0;i<=k;i++){
    		for(int j=0;j<=i;j++){
    			trans.a[j+1][i+1]=C[i][j];
    		}
    		for(int j=0;j<=i;j++){
    			trans.a[j+(k+2)][i+1]=1ll*C[i][j]*pow_2[i-j]%Mod;
    		}
    		trans.a[0][i+1]=(pow_2[i]+1)%Mod;
    	}
    	if(n==1){
    		printf("%d
    ",ans.a[0][k+1]);
    		return 0;
    	}
    	ans=ans*quick_power(trans,n-1);
    	printf("%d
    ",ans.a[0][k+1]);
    	return 0;
    }
    

    (O(k^2log n + 8klog n))

    #include <cstdio>
    typedef long long ll;
    const int Maxk=40;
    const int Mod=1000000007;
    int C[Maxk+5][Maxk+5];
    ll n;
    int k;
    void init(){
    	C[0][0]=1;
    	for(int i=1;i<=Maxk;i++){
    		C[i][0]=C[i][i]=1;
    		for(int j=1;j<i;j++){
    			C[i][j]=(C[i-1][j]+C[i-1][j-1])%Mod;
    		}
    	}
    }
    struct Matrix{
    	int a[2][2];
    	void init(){
    		a[0][0]=a[1][1]=1;
    		a[0][1]=a[1][0]=0;
    	}
    	void clear(){
    		a[0][0]=a[0][1]=a[1][0]=a[1][1]=0;
    	}
    	friend Matrix operator *(Matrix a,Matrix b){
    		Matrix ans;
    		for(int i=0;i<2;i++){
    			for(int j=0;j<2;j++){
    				ans.a[i][j]=0;
    				for(int k=0;k<2;k++){
    					ans.a[i][j]=(ans.a[i][j]+1ll*a.a[i][k]*b.a[k][j])%Mod;
    				}
    			}
    		}
    		return ans;
    	}
    	friend Matrix operator +(Matrix a,Matrix b){
    		Matrix ans;
    		for(int i=0;i<2;i++){
    			for(int j=0;j<2;j++){
    				ans.a[i][j]=(a.a[i][j]+b.a[i][j])%Mod;
    			}
    		}
    		return ans;
    	}
    	friend Matrix operator *(Matrix a,int b){
    		Matrix ans;
    		for(int i=0;i<2;i++){
    			for(int j=0;j<2;j++){
    				ans.a[i][j]=1ll*a.a[i][j]*b%Mod;
    			}
    		}
    		return ans;
    	}
    }fib,f[Maxk+5],t[Maxk+5],tmp;
    int pow_m[Maxk+5];
    void solve(ll n){
    	if(n==1){
    		for(int i=0;i<=k;i++){
    			f[i]=fib;
    		}
    		tmp=fib;
    		return;
    	}
    	ll m=(n>>1);
    	solve(m);
    	for(int i=0;i<=k;i++){
    		t[i]=f[i];
    		f[i].clear();
    	}
    	pow_m[0]=1;
    	for(int i=1,tmp_m=m%Mod;i<=k;i++){
    		pow_m[i]=1ll*pow_m[i-1]*tmp_m%Mod;
    	}
    	for(int i=0;i<=k;i++){
    		for(int j=0;j<=i;j++){
    			f[i]=f[i]+t[j]*(1ll*C[i][j]*pow_m[i-j]%Mod);
    		}
    		f[i]=f[i]*tmp;
    	}
    	for(int i=0;i<=k;i++){
    		f[i]=f[i]+t[i];
    	}
    	tmp=tmp*tmp;
    	if(n&1){
    		tmp=tmp*fib;
    		pow_m[0]=1;
    		for(int i=1,tmp_m=n%Mod;i<=k;i++){
    			pow_m[i]=1ll*pow_m[i-1]*tmp_m%Mod;
    		}
    		for(int i=0;i<=k;i++){
    			f[i]=f[i]+tmp*pow_m[i];
    		}
    	}
    }
    int main(){
    	fib.a[0][0]=fib.a[0][1]=fib.a[1][0]=1;
    	fib.a[1][1]=0;
    	scanf("%lld%d",&n,&k);
    	init();
    	solve(n);
    	printf("%d
    ",f[k].a[0][0]);
    	return 0;
    }
    
  • 相关阅读:
    MongoDB 与 MySQL 性能比较
    PySpider简易教程
    使用redis有什么缺点
    禅道
    Shell02
    Shell01
    性能测试06
    性能测试05
    性能测试04
    性能测试03
  • 原文地址:https://www.cnblogs.com/withhope/p/13916253.html
Copyright © 2011-2022 走看看