c语言数列求和while,[蓝桥杯][2014年第五届真题]斐波那契-题解(C语言代码)---C语言---数列求和公式+矩阵快速幂...

#include typedef long long ll;

typedef struct//矩阵结构体

{

ll a[2][2];

}matrix;

ll n,m,p;

ll fib_m;

ll mul_mod(ll a,ll b,ll p)//大数相乘取模

{

ll ans=0;

while(b)

{

if(b&1)

{

ans=ans+a;

ans=ans%p;

}

a=a<<1;

a=a%p;

b=b>>1;

}

return ans;

}

matrix mul_mat_1(matrix first,matrix second)//矩阵乘法

{

matrix result;

memset(result.a,0,sizeof(result.a));//初始化

for(int i=0;i<2;i++)

{

for(int j=0;j<2;j++)

{

for(int k=0;k<2;k++)

{

result.a[i][j]=(result.a[i][j]%p+mul_mod(first.a[i][k],second.a[k][j],p)%p)%p;

}

}

}

return result;

}

matrix POW_1(matrix mat,ll n)//矩阵mat的n次方

{

matrix t;

t.a[0][0]=1;//单位矩阵

t.a[0][1]=0;

t.a[1][0]=0;

t.a[1][1]=1;

while(n>0)//快速幂

{

if(n&1)//如果是奇数

{

t=mul_mat_1(t,mat);//等于结果乘当前的底数

}

n=n>>1;

mat=mul_mat_1(mat,mat);//自身平方

}

return t;

}

ll quick_fib_1(ll c)//c代表次方数

{

matrix mat,temp;

memset(mat.a,0,sizeof(mat.a));

mat.a[0][0]=1;

mat.a[0][1]=1;

mat.a[1][0]=1;

temp=POW_1(mat,c);

return temp.a[0][1];

}

matrix mul_mat(matrix first,matrix second)//矩阵乘法

{

matrix result;

memset(result.a,0,sizeof(result.a));//初始化

for(int i=0;i<2;i++)

{

for(int j=0;j<2;j++)

{

for(int k=0;k<2;k++)

{

result.a[i][j]=(result.a[i][j]+first.a[i][k]*second.a[k][j]);

}

}

}

return result;

}

matrix POW(matrix mat,ll n)//矩阵mat的n次方

{

matrix t;

t.a[0][0]=1;//单位矩阵

t.a[0][1]=0;

t.a[1][0]=0;

t.a[1][1]=1;

while(n>0)//快速幂

{

if(n&1)//如果是奇数

{

t=mul_mat(t,mat);//等于结果乘当前的底数

}

n=n>>1;

mat=mul_mat(mat,mat);//自身平方

}

return t;

}

ll quick_fib(ll c)//c代表次方数

{

ll ans;

matrix mat,temp;

memset(mat.a,0,sizeof(mat.a));

mat.a[0][0]=1;

mat.a[0][1]=1;

mat.a[1][0]=1;

temp=POW(mat,c);

return temp.a[0][1];

}

int main()

{

scanf("%lld %lld %lld",&n,&m,&p);

if(m>n+2)//如果m大于n+2,不需要计算f(m)的值

{

printf("%lld",(quick_fib_1(n+2))%p-1);//可以中途模p

return 0;

}

else//否则需要模上f(m)

{

fib_m=quick_fib(m);//算出fibm的值。这个数没办法取模,只能硬算

printf("%lld",(quick_fib(n+2))%fib_m%p-1);//第m项可以不优化求出来 ,所以第n+2项也可以不取模优化

}

return 0;

}

```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值