莫欺少年穷,修魔之旅在这开始—>算法提高课题解
推导:
Tn=f1+2f2+3f3+…+nfn
Pn=n⋅Sn−Tn=(n−1)f1+(n−2)f2+..+fn−1
Pn+1=(n+1)⋅Sn+1−Tn+1=nf1+(n−1)f2+..+2fn−1+fn
Pn+1−Pn=Sn
总结:
fn=fn−1+fn−2
Sn=Sn−1+fn
Pn=Pn−1+Sn−1
Tn=n⋅Sn−Pn
思路:
设 Fn=[fnfn+1SnPn]
Fn⋅A=Fn+1A=[0100111000110001]
Fn=F1⋅An−1
完整代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,m;
void mul(int c[][4],int a[][4],int b[][4])
{
int temp[4][4]={0};
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
temp[i][j]=(temp[i][j]+(LL)a[i][k]*b[k][j])%m;
memcpy(c,temp,sizeof temp);
}
int main()
{
cin>>n>>m;
int f[4][4]={1,1,1,0};
int a[4][4]={
{0,1,0,0},
{1,1,1,0},
{0,0,1,1},
{0,0,0,1}
};
int k=n-1;
while(k) //矩阵快速幂
{
if(k&1) mul(f,f,a);
mul(a,a,a);
k>>=1;
}
cout<<(((LL)n*f[0][2]-f[0][3])%m+m)%m<<endl;
return 0;
}