题目
算法思路
- 公式推不出来,只能推矩阵了
- 因为 F ( i ) = F ( i − 1 ) + F ( i − 2 ) F(i)=F(i-1)+F(i-2) F(i)=F(i−1)+F(i−2),设原来的数列为f(i),则 f ( i ) ∗ 8 = f ( i − 1 ) ∗ 4 + f ( i − 2 ) ∗ 2 f(i)*8=f(i-1)*4+f(i-2)*2 f(i)∗8=f(i−1)∗4+f(i−2)∗2,即 f ( i ) = f ( i − 1 ) 2 + f ( i − 2 ) 4 f(i)=\cfrac{f(i-1)}{2}+\cfrac{f(i-2)}{4} f(i)=2f(i−1)+4f(i−2)
- 因为题目要求解的是 s u m ( i ) sum(i) sum(i),显然 s u m ( i ) = s u m ( i − 1 ) + f ( i ) sum(i)=sum(i-1)+f(i) sum(i)=sum(i−1)+f(i)
- 这个时候我们就可以设立初始矩阵的状态,和操作矩阵了,设立 [ f ( x ) , f ( x − 1 ) , s u m ( x − 1 ) ] T [f(x),f(x-1),sum(x-1)]^{T} [f(x),f(x−1),sum(x−1)]T为所求矩阵(列向量),下一状态为 [ f ( x + 1 ) , f ( x ) , s u m ( x ) ] T [f(x+1),f(x),sum(x)]^{T} [f(x+1),f(x),sum(x)]T
- 由 f ( x + 1 ) = f ( x ) 2 + f ( x − 1 ) 4 f(x+1)=\cfrac{f(x)}{2}+\cfrac{f(x-1)}{4} f(x+1)=2f(x)+4f(x−1)得,操作矩阵的第一列为 [ 1 2 , 1 4 , 0 ] T [\cfrac{1}{2},\cfrac{1}{4},0]^T [21,41,0]T
- 由 f ( x ) = f ( x ) f(x)=f(x) f(x)=f(x)得到操作矩阵第二列为 [ 1 , 0 , 0 ] [1,0,0] [1,0,0]
- 由 s u m ( x ) = s u m ( x − 1 ) + f ( x ) sum(x)=sum(x-1)+f(x) sum(x)=sum(x−1)+f(x)得到操作矩阵第三列为 [ 1 , 0 , 1 ] [1,0,1] [1,0,1]
- 最终这样我们就得出了操作矩阵,然后我们用矩阵快速幂算出 A n − 1 A^{n-1} An−1(的第三列),再乘以初始矩阵 [ f ( 2 ) , f ( 1 ) , s u m ( 1 ) ] T = [ 0.25 , 0.5 , 0.5 ] T [f(2),f(1),sum(1)]^T=[0.25,0.5,0.5]^T [f(2),f(1),sum(1)]T=[0.25,0.5,0.5]T,则得到最终的答案矩阵s,s[3]即为所求答案
代码实现
(队友写的,以后还是写结构体好一点,不然最后一行,每次迷迷糊糊)
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
#define el '\n'
#define cl putchar('\n')
#define pb push_back
#define eb emplace_back
#define fir first
#define sec second
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vci;
typedef map<int,int> mii;
typedef mii::iterator mii_it;
const int N=1e5+10,M=1e3+10;
double a[5][5],b[5][5],ans[5][5];
void chenans() {
for(int i=1; i<=3; i++) {
for(int j=1; j<=3; j++)b[i][j]=ans[i][j];
}
for(int i=1; i<=3; i++) {
for(int j=1; j<=3; j++) {
ans[i][j]=0;
for(int k=1; k<=3; k++) {
ans[i][j]+=b[i][k]*a[k][j];
}
}
}
}
void chena() {
for(int i=1; i<=3; i++) {
for(int j=1; j<=3; j++)b[i][j]=a[i][j];
}
for(int i=1; i<=3; i++) {
for(int j=1; j<=3; j++) {
a[i][j]=0;
for(int k=1; k<=3; k++) {
a[i][j]+=b[i][k]*b[k][j];
}
}
}
}
void ksm(int b) {
for(int i=1; i<=3; i++)ans[i][i]=1;
a[1][1]=0.5;
a[2][1]=0.25;
a[1][2]=1;
a[1][3]=1;
a[3][3]=1;
while(b) {
if(b&1)chenans();
b=b/2;
chena();
}
}
int main() {
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
ksm(n-1);
// for(int i=1;i<=3;i++){
// for(int j=1;j<=3;j++){
// printf("%.6f ",ans[i][j]);
// }
// cl;
// }
printf("%.8f",ans[1][3]*0.25+ans[2][3]*0.5+ans[3][3]*0.5);
// cin>>T;
// while(T--) {
//
// }
}