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) 的值。

样例
输入复制
5 5
输出复制
1
 
数据范围与提示

对于 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

_________________________________________

 
 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 }
View Code
原文地址:https://www.cnblogs.com/gryzy/p/14527656.html