链接:点击打开链接
题意:G(i)=k*i+b,f(0)=0,f(1)=1,f(n)=f(n-1)+f(n-2) (n>=2),求 f(g(i)) 的和0<=i<n
代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
long long m;
struct node{
long long m[2][2];
};
struct node1{
long long m[4][4];
};
node P={0,1,
1,1};
node I={1,0,
0,1}; //S(n)=f(b)+f(k+b)+f(2*k+b)+...+f((n-1)*k+b)
node1 P1={0,0,1,0, //f[n]根据矩阵连乘,f[n]可以用矩阵表示
0,0,0,1, //所以f(n)=Pⁿ.m[0][1]
0,0,1,0, //S(n)=P^b*(I+P^k+P^(2k)+......+P^((n-1)k)).m[0][1];
0,0,0,1}; //令R为P^k,I为单位阵,构造下面这个阵:
node1 I1={1,0,0,0, //|A I|
0,1,0,0, //|0 I|
0,0,1,0, //通过计算会发现这个阵的n次幂的右上角为I+A+A^2+ ...+A^(n-1)
0,0,0,1}; //从而求出I+R+R^2+...+R^(n-1),然后求出S(n)
node mul(node a,node b){
int i,j,k;
node c;
for(i=0;i<2;i++)
for(j=0;j<2;j++){
c.m[i][j]=0;
for(k=0;k<2;k++)
c.m[i][j]+=(a.m[i][k]*b.m[k][j])%m;
c.m[i][j]%=m;
}
return c;
}
node1 mul(node1 a,node1 b){
int i,j,k;
node1 c;
for(i=0;i<4;i++)
for(j=0;j<4;j++){
c.m[i][j]=0;
for(k=0;k<4;k++)
c.m[i][j]+=(a.m[i][k]*b.m[k][j])%m;
c.m[i][j]%=m;
}
return c;
}
node quickmod(long long n){
node a,b;
a=P;b=I;
while(n){
if(n&1)
b=mul(b,a);
n>>=1;
a=mul(a,a);
}
return b;
}
node1 quickmod1(long long n){
node1 a,b;
a=P1;b=I1;
while(n){
if(n&1)
b=mul(b,a);
n>>=1;
a=mul(a,a);
}
return b;
} //矩阵快速幂模板
int main(){
long long k,b,n,sum;
node temp,temp1;
node1 cur;
while(cin>>k>>b>>n>>m){
temp=quickmod(b);
temp1=quickmod(k);
P1.m[0][0]=temp1.m[0][0];P1.m[0][1]=temp1.m[0][1];
P1.m[1][0]=temp1.m[1][0];P1.m[1][1]=temp1.m[1][1];
cur=quickmod1(n);
sum=(temp.m[0][0]*cur.m[0][3]%m)+(temp.m[0][1]*cur.m[1][3]%m);
sum%=m; //构造矩阵后做乘法
cout<<sum<<endl;
}
return 0;
}