loj10222
佳佳对数学,尤其对数列十分感兴趣。在研究完 Fibonacci 数列后,他创造出许多稀奇古怪的数列。例如用 s(n) 表示 Fibonacci 前 n 项和 mod m 的值,即 s(n)=(f_1+f_2+f_3+...+f_n)mod m,其中 f_1=f_2=1,f_i=f_{i-1}+f_{i-2}。可这对佳佳来说还是小菜一碟。
终于,她找到了一个自己解决不了的问题。用 t(n)=(f_1+2*f_2+3*f_3+...+n*f_n)mod m 表示 Fibonacci 数列前 n 项变形后的和 mod m 的值。
现在佳佳告诉你了一个 n 和 m,请求出 t(n) 的值。
输入数据包括一行,两个用空格隔开的整数n,m 。
仅一行,t(n) 的值。
对于 100% 的数据1<=n,m<=2^31-1。
_________________________________________
刚做了几个关于矩阵乘法的题,这个题目没推出来。看了题解才会的!
刚开始看到:T(N)=T(N-1)+N*F_N
但是这个用矩阵没法做,系数N在不断的变。
$T(n)=f_1+2*f_2+...+n*f_n$
$T(n)=\sum_{i-1}^ni*f_i$
$S(n)=f_1+f_2+...+f_n$
$S(n)=\sum_{i=1}^nf_i$
$n*S(n)=\sum_{i=1}^nn*f_i$
$n*S(n)-T(n)=\sum_{i=1}^n(n-i)*f_i$
当i==n时,第n-i==0,也就可以去掉了,得到
$n*S(n)-T(n)=\sum_{i=1}^{n-1}(n-i)*f_i$
设$P(n)=n*S(n)-T(n)$
则$P(n+1)=P(n)+S(n)$
开始矩阵为
s=[P(1),S(1),f_1,f_{0}]
矩阵p为
1 0 0 0
1 1 0 0
0 1 1 1
0 1 1 0
那么$s*p^{n-1}$就可以得到P(n)和S(n),n*S(n)-P(n)就是结果。因为要对m取模,所以真正的结果为(n*S(n)-P(n)+m)%m
_________________________________________
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 ll n,m; 5 struct node 6 { 7 ll sz[4][4]; 8 node(){memset(sz,0,sizeof sz);} 9 }s,p,st; 10 11 node cheng(node a,node b) 12 { 13 node c; 14 for(int i=0;i<4;++i) 15 for(int j=0;j<4;++j) 16 for(int k=0;k<4;++k) 17 c.sz[i][j]=(c.sz[i][j]+a.sz[i][k]*b.sz[k][j])%m; 18 return c; 19 } 20 21 node pwr(int n) 22 { 23 if(n==0)return st; 24 node tp=pwr(n/2); 25 node ans=cheng(tp,tp); 26 if(n%2)ans=cheng(ans,p); 27 return ans; 28 } 29 30 int main() 31 { 32 scanf("%lld%lld",&n,&m); 33 for(int i=0;i<4;++i)st.sz[i][i]=1; 34 p.sz[0][0]=p.sz[1][0]=p.sz[1][1]=p.sz[2][1]=p.sz[2][2]=p.sz[2][3]=p.sz[3][1]=p.sz[3][2]=1; 35 s.sz[0][1]=s.sz[0][2]=1; 36 node tp=pwr(n-1); 37 node ans=cheng(s,tp); 38 cout<<(ans.sz[0][1]*n-ans.sz[0][0]+m)%m<<endl; 39 return 0; 40 }