传送门:HIT 2255
题意:给一个数列,变形的斐波那契数列.f[0]=a,f[1]=b,n>=2,f[n]=p*f[n-1]+q*f[n-2]。求第s项到第e项的和。
题解:矩阵快速幂。我推出的矩阵是3×3的:1 p q s[1] s[2]
0 p q × f[1] = f[n]
0 1 0 f[0] f[n-1]
(数列s为数列f的前n项和)
矩阵的n次幂对应s[n+1]。最后,s[e-1]-s[s-2]即为结果(两个s代表的意义不同)
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
#include <map>
using namespace std;
const int MAX=3;
const int MOD=10000000;
typedef struct
{
long long m[MAX][MAX];
void set()
{
memset(m,0,sizeof(m));
}
}Matrix;
long long pp,qq,aa,bb,ss,ee,ans;
Matrix T1={1,0,0,0,0,0,0,0,1};
Matrix T2={1,0,0,0,1,0,0,0,1};
Matrix matrixmul(Matrix a,Matrix b)
{
int i,j,k;
Matrix c;
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++)
{
c.m[i][j]=0;
for(k=0;k<MAX;k++)
c.m[i][j]+=(a.m[i][k]*b.m[k][j])%MOD;
c.m[i][j]%=MOD;
}
return c;
}
Matrix quickpow(int n)
{
Matrix m=T1,b=T2;
while(n>=1)
{
if(n&1)
b=matrixmul(b,m);
n=n>>1;
m=matrixmul(m,m);
}
return b;
}
void inti(int p,int q)//初始化矩阵
{
T1.set();
T1.m[0][0]=1;
T1.m[0][1]=p;
T1.m[0][2]=q;
T1.m[1][1]=p;
T1.m[1][2]=q;
T1.m[2][1]=1;
}
int main()
{
Matrix S1,S2;
long long k1,k2;
int t;
cin>>t;
while(t--)
{
cin>>aa>>bb>>pp>>qq>>ss>>ee;
inti(pp,qq);
if(ee>=2)
S1=quickpow(ee-1);
if(ss>2)
S2=quickpow(ss-2);
if(ss==0) k2=0;
else if(ss==1) k2=aa;
else if(ss==2) k2=bb+aa;
else k2=((S2.m[0][0]*((aa+bb)%MOD))%MOD+(S2.m[0][1]*bb)%MOD+(S2.m[0][2]*aa)%MOD)%MOD;
if(ee==0) k1=aa;
else if(ee==1) k1=bb+aa;
else k1=((S1.m[0][0]*((aa+bb)%MOD))%MOD+(S1.m[0][1]*bb)%MOD+(S1.m[0][2]*aa)%MOD)%MOD;
ans=k1-k2;
if(ans<0) ans+=MOD;
cout<<ans<<endl;
}
return 0;
}